Socket套接字/TCP
2015-11-22 22:10
661 查看
关于网络编程,就不得不提Socket套接字,下面就来讲讲对Socket的一些理解以及运用!
套接字(Socket),指的是一个程序的IP和端口号的结合。
我们可以这样理解:所谓网络通信,实际上指的是两台主机上面的两个程序之间的通信,
两个程序在进行通信(数据交换)的时候需要建立起一个“连接”,我们就可以认为这个连接就是一个网络套接字.
假设A主机的程序1要和B主机的程序2进行数据交换,
首先A主机的程序1需要通过B主机的IP找到B主机,然后再通过程序的端口号找到B主机的程序2,
找到之后A主机的程序1和B主机的程序2之间就建立起了一个连接(Socket),通过这个连接就可以实现两者之间的数据交换。
当A的程序1和B的程序2建立起连接(Socket)之后,不是直接通过socket进行数据交换的,
而是通过Socket里面的流进行通信的。
在Socket有两根流,一根是从A到B,另一根是从B到A的,对于同一根流,如果对于A是输出,那么对于B就是输入。
如下图:
熟悉了socket的概念之后,下面通过一个简单的实例来模拟一下socket的使用!
程序场景:A主机的程序1连接B主机程序2进行网络通信。此处B主机作为服务器![java.net.Socket]包
B主机程序2
注意:
accept() : 让服务器等待网络连接,服务器在等待网络连接的时候,处于一个等待状态,不会往下执行,直到有客户端发送请求,服务器在接受到了请求之后才会继续往下执行!!所以上面accept方法行下面的的代码在启动服务器[MyServer]时不会立即执行!!
A主机的程序1
上面程序当然得先启动服务器[MyServer],然后客户端[MyClient]才能通过socket正常连接!!
此处特别注意,先启动服务器客户端才能连接,否则先启动客户端的话会报错!!!为什么会这样呢,这就是典型的
TCP模式,客户端必须确定可以建立连接,需要服务器端返回可以连接(三次握手)的信号!!!!
上面的实例只是单方面的客户端向服务器发送消息,但是很多情况下是需要客户端和服务器互相发送消息的,有点像QQ的意思!!如下图:
以下为通过线程发送和接收信息,Socket持续通信的实例代码:
服务器:
客户端:
发送信息线程:
接收信息线程:
文中有考虑不周到的地方,欢迎大家指正,共同进步!!!!!
以上
套接字(Socket),指的是一个程序的IP和端口号的结合。
我们可以这样理解:所谓网络通信,实际上指的是两台主机上面的两个程序之间的通信,
两个程序在进行通信(数据交换)的时候需要建立起一个“连接”,我们就可以认为这个连接就是一个网络套接字.
假设A主机的程序1要和B主机的程序2进行数据交换,
首先A主机的程序1需要通过B主机的IP找到B主机,然后再通过程序的端口号找到B主机的程序2,
找到之后A主机的程序1和B主机的程序2之间就建立起了一个连接(Socket),通过这个连接就可以实现两者之间的数据交换。
当A的程序1和B的程序2建立起连接(Socket)之后,不是直接通过socket进行数据交换的,
而是通过Socket里面的流进行通信的。
在Socket有两根流,一根是从A到B,另一根是从B到A的,对于同一根流,如果对于A是输出,那么对于B就是输入。
如下图:
熟悉了socket的概念之后,下面通过一个简单的实例来模拟一下socket的使用!
程序场景:A主机的程序1连接B主机程序2进行网络通信。此处B主机作为服务器![java.net.Socket]包
B主机程序2
package com.socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * 这个类对应的是B主机的程序2 * @author admin * */ public class MyServer { public static void main(String[] args) { try { // 创建网络服务器,指定端口,提供给客户端连接 ServerSocket server = new ServerSocket(9555); // 让服务器等待网络连接,服务器在等待网络连接的时候,处于一个等待状态 // 不会往下执行,直到有客户端发送请求,服务器在接受到了请求之后才会继续往下执行 Socket socket = server.accept(); // 此处直到有客户端发送请求时,才会执行 System.out.println("此处直到有客户端发送请求时,才会执行!!!"); // 通过socket获取到它的输入流 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); // 打印客户端输入的内容 String str=null; while((str=br.readLine())!=null) { System.out.println(str); } br.close(); } catch (IOException e) { e.printStackTrace(); } } }
注意:
accept() : 让服务器等待网络连接,服务器在等待网络连接的时候,处于一个等待状态,不会往下执行,直到有客户端发送请求,服务器在接受到了请求之后才会继续往下执行!!所以上面accept方法行下面的的代码在启动服务器[MyServer]时不会立即执行!!
A主机的程序1
package com.socket; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 这个类对应的是A主机的程序1 * @author admin * */ public class MyClient { public static void main(String[] args) { try { // 通过服务器的IP和端口号创建socket请求,一旦请求成功就创建socket Socket socket = new Socket("localhost", 9555); // 因为是客户端向服务器发送消息,所以获取输出流 OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); pw.println("A主机的程序1连接B主机程序2进行网络通信----演示"); // 此处记得flush() pw.flush(); // 关闭流,养成习惯 pw.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
上面程序当然得先启动服务器[MyServer],然后客户端[MyClient]才能通过socket正常连接!!
此处特别注意,先启动服务器客户端才能连接,否则先启动客户端的话会报错!!!为什么会这样呢,这就是典型的
TCP模式,客户端必须确定可以建立连接,需要服务器端返回可以连接(三次握手)的信号!!!!
上面的实例只是单方面的客户端向服务器发送消息,但是很多情况下是需要客户端和服务器互相发送消息的,有点像QQ的意思!!如下图:
以下为通过线程发送和接收信息,Socket持续通信的实例代码:
服务器:
package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * 服务器 * @author admin * */ public class TestServer { public static void main(String[] args) { try { // 创建服务器端口,给客户端提供连接 ServerSocket server = new ServerSocket(9555); // 等待客户端连接 Socket socket = server.accept(); // 从socket获取到输出流 OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); // 从socket获取到输入流 InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); ReceiveMsg rm = new ReceiveMsg(br); SendMsg sm = new SendMsg(pw); // 启动线程 sm.start(); rm.start(); } catch (IOException e) { e.printStackTrace(); } } }
客户端:
package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端 * @author admin * */ public class TestClient { public static void main(String[] args) { try { // 连接服务器 Socket socket = new Socket("localhost",9555); // 从socket获取到输入流 InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); // 从socket获取到输出流 OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); // 启动接收和发送两个线程 ReceiveMsg rm = new ReceiveMsg(br); SendMsg sm = new SendMsg(pw); sm.start(); rm.start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
发送信息线程:
package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; /** * 此线程用于发送信息 * @author Admin * */ public class SendMsg extends Thread{ // 输出流 private PrintWriter pw; public SendMsg(PrintWriter pw){ this.pw = pw; } // 此线程用于发送信息 public void run(){ // 输入流,从控制台读取信息 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str=null; try { // 输出信息 while((str=br.readLine())!=null){ pw.println(str); pw.flush(); } // 关闭流 pw.close(); } catch (IOException e) { e.printStackTrace(); } } }
接收信息线程:
package com.test; import java.io.BufferedReader; import java.io.IOException; /** * 此线程用于接收信息 * @author Admin * */ public class ReceiveMsg extends Thread { // 输入流 private BufferedReader br; public ReceiveMsg(BufferedReader br){ this.br=br; } // 此线程用于接收信息 public void run(){ String str=null; try { // 读取信息 while((str=br.readLine())!=null){ System.out.println(str); } br.close(); } catch (IOException e) { e.printStackTrace(); } } }
文中有考虑不周到的地方,欢迎大家指正,共同进步!!!!!
以上
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- java socket 注意的地方
- java socket 注意的地方
- C#基于socket模拟http请求的方法
- Lua下基本的网络编程示例
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- 使用C#来编写一个异步的Socket服务器
- C#使用Socket快速判断数据库连接是否正常的方法
- 科学知识:理解socket
- linux网络编程用到的网络函数详解用和使用示例
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket
- C#网络编程基础之进程和线程详解
- C++ 网络编程 总结
- C#使用Socket上传并保存图片的方法
- 深入php socket的讲解与实例分析
- Linux网络编程之UDP Socket程序示例