使用Socket完成客户端与服务端的双向通信
有些公司面试中常常要求白板编程,其中Socket编程是个出现频率比较高的题目。在此记录一下自己学习Socket编程的心得,做一个简单的双向通信的例子。
要求
客户端发送数据,服务端回显相同的数据。
服务端:
package day1106;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Socket之服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("我是服务端");
//监听端口
int port = 43438;
ServerSocket serverSocket = new ServerSocket(port);
//建立连接
Socket socket = serverSocket.accept();
//获得客户端传来的数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len, "utf-8"));
System.out.println("服务端正在从输入流中读数据");
}
System.out.println("服务端收到了:" + sb.toString());
//接收到数据后,回显收到的数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write(sb.toString().getBytes("utf-8"));
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
}
}
客户端:
package day1106;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
/**
* Socket之客户端
*/
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("我是客户端");
//指定目标主机ip与端口
String host = "127.0.0.1";
int port = 43438;
Socket socket = new Socket(host, port);
//想服务端发送数据
OutputStream outputStream = socket.getOutputStream();
//接收用户输入
Scanner sc = new Scanner(System.in);
String message = sc.nextLine();
outputStream.write(message.getBytes("utf-8"));
outputStream.flush();
//终止发送数据,客户端现在只接收数据
//如果不加shutdownOutput,服务器端一直阻塞在read()方法中,导致客户端无法收到服务端回显的数据
//shutdownOutput只关闭客户端向服务端的输出流,并不会关闭整个Socket的连接
socket.shutdownOutput();
//从服务端接收数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len, "utf-8"));
System.out.println("客户端正在从输入流中读数据");
}
System.out.println("来自服务端的回显:" + sb.toString());
//调用close方法,会直接关闭整个Socket连接
outputStream.close();
inputStream.close();
socket.close();
}
}
发送之前的截图
客户端:
服务端:
发送之后的截图:
客户端:
服务端: