【网络编程】三、Socket 和 ServerSocket
一、Socket
在客户/服务器通信模式中,客户端需要主动创建与服务器连接的Socket。服务器端收到客户的链接请求,也会创建与客户连接的Socket.
Socket可以看作是通信连接两端的数据收发器。服务器与客户都通过套接字来收发数据。
二、ServerSocket
在客户/服务器通信模式中,服务器端需要创建监听特定的端口的ServerSocket.ServerSocket服务接收客户端的链接请求。
三、服务器和客户端代码示意
3.1、客户端代码
package com.study.sxf.common.web.socket.io.step1; import java.io.*; import java.net.Socket; /** * @Date 2022/3/12 2:25 PM **/ public class EchoClient { private static Integer serverPort = 8080; private static String serverIp = "127.0.0.1"; public static void main(String[] args) throws IOException { EchoClient echoClient = new EchoClient(); //step1:建立连接 Socket socket = echoClient.buildSocket(); System.out.println("客户端连接建立成功"); //step2:发送请求 PrintWriter printWriter = echoClient.getPrintWriter(socket); String req = "我是小明"; System.out.println("客户端发送请求=>" + req); printWriter.println(req); socket.shutdownOutput(); //step3:接收响应 BufferedReader bufferedReader = echoClient.getReader(socket); String resp = echoClient.readResponse(bufferedReader); System.out.println("客户单接收响应=>" + resp); //step4:关闭客户端连接 System.out.println("客户端关闭连接"); socket.close(); } /** * 建立连接 * * @return * @throws IOException */ private Socket buildSocket() throws IOException { return new Socket(serverIp, serverPort); } /** * 建立发送请求的管道 * * @param socket * @return * @throws IOException */ private PrintWriter getPrintWriter(Socket socket) throws IOException { return new PrintWriter(socket.getOutputStream(),true); } /** * 建立接收响应的管道 * * @param socket * @return * @throws IOException */ private BufferedReader getReader(Socket socket) throws IOException { return new BufferedReader(new InputStreamReader(socket.getInputStream())); } /** * 读取响应 * @param bufferedReader * @return * @throws IOException */ private String readResponse(BufferedReader bufferedReader) throws IOException { StringBuffer resp = new StringBuffer(); String msg= null; // String msg = bufferedReader.readLine(); // return msg; while ((msg = bufferedReader.readLine()) != null) { resp.append(msg); } return resp.toString(); } }
3.2、服务端代码
package com.study.sxf.common.web.socket.io.step1; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * @Date 2022/3/12 1:58 PM **/ public class EchoServer { private static Integer serverPort = 8080; public static void main(String[] args) throws IOException { EchoServer echoServer = new EchoServer(); ServerSocket serverSocket = null; try { serverSocket = echoServer.buildServerSocket(); while (true) { //step1:接收请求 Socket socket = serverSocket.accept(); System.out.println("服务器收到1个客户端请求,客户端地址=" + socket.getInetAddress() + "客户端端口号" + socket.getPort()); BufferedReader bufferedReader = echoServer.getBufferedReader(socket); String req = echoServer.readRequest(bufferedReader); System.out.println("客户端发送的请求为=" + req); //step2:业务处理 String resp = req + "服务端已处理成功"; //step3:进行业务响应 PrintWriter printWriter = echoServer.getPrintWriter(socket); echoServer.ackResponse(printWriter,resp); //step4:关闭客户端连接 System.out.println("服务端关闭连接"); socket.close(); } } catch (Exception e) { System.out.println("服务器异常退出e=" + e.getMessage()); } finally { if (serverSocket != null) { serverSocket.close(); } } } /** * 构建1个服务器 * * @return * @throws IOException */ private ServerSocket buildServerSocket() throws IOException { System.out.println("=======服务器准备启动====="); ServerSocket serverSocket = new ServerSocket(serverPort); System.out.println("=======服务器启动成功"); return serverSocket; } /** * 获取输入流,读取客户端请求 * * @param socket * @return * @throws IOException */ private BufferedReader getBufferedReader(Socket socket) throws IOException { InputStream inputStream = socket.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream); return new BufferedReader(reader); } /** * 读取请求 * * @param bufferedReader * @return */ private String readRequest(BufferedReader bufferedReader) throws IOException { StringBuffer stringBuffer = new StringBuffer(); String msg=null; // String msg =bufferedReader.readLine(); // return msg; while ((msg = bufferedReader.readLine()) != null) { //读取一行后,再读第二行会被阻塞住 stringBuffer.append(msg); } return stringBuffer.toString(); } /** * 获取输出流管道,进行响应 * * @param socket * @return * @throws IOException */ private PrintWriter getPrintWriter(Socket socket) throws IOException { OutputStream outputStream = socket.getOutputStream(); return new PrintWriter(outputStream,true); } private void ackResponse(PrintWriter printWriter, String resp) { System.out.println("服务端响应="+resp); printWriter.println(resp); } }