首先启动服务端,客户端通过TCP的三次握手与服务端建立连接;
然后,客户端发送一段字符串,服务端收到字符串后,原封不动的发回给客户端。
ECHO 程序是网络编程通信交互的一个经典案例,称为回应程序,即客户端输入哪些内容,服务端会在这些内容前加上“ECHO”并将信息发回给客户端。
EchoServer.java
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class EchoServer { private ServerSocket server; public EchoServer() throws IOException { // 创建服务端套接字对象 this.server = new ServerSocket(8888); System.out.println("服务器启动" + "在" + 8888 + "端口监听连接请求"); } // 服务器主要的处理逻辑 public void service() { // 是否关闭服务端连接 boolean flag = true; while (flag) { Socket socket = null; try { // 获取连接的客户端套接字对象 socket = server.accept(); // 获取socket相关的输入流和输出流 BufferedReader reader = getReader(socket); BufferedWriter writer = getWriter(socket); // 保存客户端发送的数据 String data = null; // 读取客户端发送的数据 while ((data = reader.readLine()) != null) { // 当获取的信息是“bye”时,关闭流 if ("bye".equals(data)) { flag = false; if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } break; } else { System.out.println("来自客户端的数据:" + data); // 回显给客户端的数据 writer.write("echo:" + data); // 插入一个行分割符,readLine()方法用来判定字符串有没结束 writer.newLine(); // 刷新输出缓冲区 writer.flush(); } } } catch (IOException e) { // 设置结束循环 flag = false; } finally { try { if (server != null && (!server.isClosed())) { server.close(); System.out.println("服务端关闭"); } } catch (IOException e) { e.printStackTrace(); } } } } // 获取socket相关的输入流对象 private BufferedReader getReader(Socket socket) throws IOException { InputStream in = socket.getInputStream(); return new BufferedReader(new InputStreamReader(in)); } // 获取socket相关的输出流对象 private BufferedWriter getWriter(Socket socket) throws IOException { OutputStream out = socket.getOutputStream(); return new BufferedWriter(new OutputStreamWriter(out)); } public static void main(String arg[]) throws IOException { new EchoServer().service(); } }
EchoClient.java
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; public class EchoClient { private Socket socket; public EchoClient() { try { // 创建客户端套接字对象 this.socket = new Socket("127.0.0.1", 8888); } catch (IOException e) { e.printStackTrace(); } } public void talkToServer() { System.out.println("请输入要发送给服务端的数据:"); BufferedReader localReader = null; String data = null; // 获取客户端套接字相关的输入流和输出流 BufferedReader reader = getReader(socket); BufferedWriter writer = getWriter(socket); try { // 创建读取用户输入的读取流 localReader = new BufferedReader(new InputStreamReader(System.in)); while ((data = localReader.readLine()) != null) { // 如果客户端输入的数据是"bye",则关闭I/O流 if ("bye".equals(data)) { System.out.println("客服端关闭!"); if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } break; } else { // readLine方法必须读取到行分割符才返回读取。所以传递给输入流的字符串必须包含行分割符 System.out.println("客户端输出的数据--->\t" + data); writer.write(data); // 插入一个行分隔符,作为内容结束的标识 writer.newLine(); // 非常重要的是必须显式的将数据推送到服务器哪里去 writer.flush(); // 读取服务端返回的数据 System.out.println("服务器响应的数据--->\t " + reader.readLine()); } } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭客户端套接字连接 try { if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } // 获取客户端套接字相关的输出流 private BufferedWriter getWriter(Socket socket) { try { OutputStream out = null; BufferedWriter writer = null; out = socket.getOutputStream(); writer = new BufferedWriter(new OutputStreamWriter(out)); return writer; } catch (Exception e) { e.printStackTrace(); } return null; } // 获取客户端套接字相关的输入流 private BufferedReader getReader(Socket socket) { try { InputStream in = null; BufferedReader reader = null; in = socket.getInputStream(); reader = new BufferedReader(new InputStreamReader(in)); return reader; } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { new EchoClient().talkToServer(); } }