使用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();
}
}
發送之前的截圖
客戶端:
服務端:
發送之後的截圖:
客戶端:
服務端: