一、Socket简介:
1、什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
二、Socket通信实例①:
功能:客户端发送一条请求,服务器端接收,打印,向客户端返回一条信息,客户端接收,打印。
1、服务器端代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * 该服务器端接收客户端发送的数据,并向客户端发送一条响应信息 * @author Administrator * */ public class MyServer { public static void main(String[] args) { ServerSocket server = null; Socket client = null; PrintWriter pw = null; BufferedReader br = null; try { server = new ServerSocket(6789); //获取连接 client = server.accept(); pw = new PrintWriter(client.getOutputStream()); //接收客户端传递的数据 br = new BufferedReader(new InputStreamReader(client.getInputStream())); System.out.print("Info From Client:"); //此处仅读一行,若采用while()的方式,如果读取不到结束标记,会阻塞 System.out.println(br.readLine()); System.out.println("server over..."); //向客户端写回数据 pw.print("Hello Client!! I am Server!!!\r\n"); pw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 try { if(br != null) { br.close(); } if(pw != null) { pw.close(); } if(client != null) { client.close(); } if(server != null) { server.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
2、客户端代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 该客户端类仅实现以下功能: * 向服务器发送信息,接收从服务器返回的数据,仅读取一行 * @author Administrator * */ public class MyClient { public static void main(String[] args) { Socket socket = null; PrintWriter pw = null; BufferedReader br = null; try { //指定服务器地址+端口 socket = new Socket("127.0.0.1", 6789); pw = new PrintWriter(socket.getOutputStream()); br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 向服务器端发送数据 pw.write("Hello Server!!! I am Client!!!\r\n"); pw.flush(); // 接收服务器端返回的数据 System.out.print("Info From Server:"); //此处仅读一行,若采用while()的方式,如果没有结束标记,会阻塞 System.out.println(br.readLine()); System.out.println("client over..."); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } if (pw != null) { pw.close(); } if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
3、注意事项:
防止方式阻塞导致程序卡死。Socket阻塞或者是流读取的阻塞。
三、Socket通信多线程版本:
实际使用时肯定是服务端接收到一个请求就开启一个线程来处理对应的请求。
四、其他思路扩展:
1、java.nio包提供了支持非阻塞通信的类,主要包括:
?ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。 ?SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。 ?Selector:为ServerSocketChannel监控接收连接就绪事件,为SocketChannel监控连接就绪、读就绪和写就绪事件。 ?SelectionKey:代表ServerSocketChannel以及SocketChannel向Selector注册事件的句柄。当一个SelectionKey对象位于Selector对象的selected-keys集合中,就表示与这个SelectionKey对象相关的事件发生了。 ServerSocketChannel以及SocketChannel都是SelectableChannel的子类,如图3所示。SelectableChannel类以及其子类都能委托Selector来监控它们可能发生的一些事件,这种委托过程也称为注册事件过程。
待续......