|
普通Socket一般分为ServerSocket和Socket两大类。
ServerSocket用于服务端,其accept()方法可以用来监听请求,该方法方法在连接传入之前一直阻塞,也就是说服务端程序会停留在该方法调用处,直到有客户端请求连接进来。accept()方法会返回一个Socket对象。 Socket用来传输数据,JDK中描述为套接字,理解起来还是有点困难。TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)。一般客户端使用Socket绑定服务端IP以及监听端口发起请求并传输数据。
用大白话说就是:ServerSocket是服务端用来检测客户端是否使用Socket发起请求了,如果有,拿到Socket,从其中拿到客户端的请求数据,再将响应数据写入Socket,这其中读取写入数据又设计IO流操作。客户端使用Socket对象发送请求数据到服务端,然后在从该socket中拿到服务端的响应数据。
代码实现如下(代码中注释写的很详细): 服务端模拟实现: /* 模拟服务器端-普通Socket实现 */ public class Server { public static void main(String[] args) { try { //创建一个ServerSocket,绑定监听端口为8080 ServerSocket serverSocket = new ServerSocket(8080); //调用accept()方法监听客户端请求,该方法是阻塞方法,程序会停留在这里直到有客户端请求服务端的8080接口 //Socket用于通信中的数据传输 Socket socket = serverSocket.accept(); //创建BufferedReader接收来自客户端的请求数据,源数据流对象来自客户端发起请求的Socket BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String requestData = bufferedReader.readLine(); System.out.println("接收到客户端的请求数据:" + requestData); //创建PrintWriter发送服务端响应数据,接收数据流对象也来自Socket PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); //写入响应数据 printWriter.println("服务端已接收到你的请求,响应数据为(服务端响应数据)!"); //使用flush()方法强制发送数据而不是等到缓冲区满了后才发送 printWriter.flush(); //关闭资源 printWriter.close(); bufferedReader.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
客户端程序如下: /* 模拟客户端-普通Socket实现 */ public class Client { public static void main(String[] args) { try { //创建Socket用来发起请求,设置请求IP为本机,端口号为8080 Socket socket = new Socket("127.0.0.1",8080); //通过Socket的流对象创建PrintWriter用于发送请求数据,创建BufferedReader用于接收服务端响应数据 PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //发送数据 String requestData = "客户端请求数据"; printWriter.println(requestData); printWriter.flush(); //接收服务端响应数据 String responseData = bufferedReader.readLine(); System.out.println("接收到服务端的响应数据为:" + responseData); //关闭资源 printWriter.close(); bufferedReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } 先启动服务端程序,再启动客户端程序。输出如下: 服务端先启动后没有输出。 启动客户端后: 服务端输出: 客户端输出: |