報錯信息如下圖:

客戶端代碼:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TcpSend {
public static void main(String[] args) throws IOException {
Socket sc = new Socket("127.0.0.1", 11223);
OutputStream out = sc.getOutputStream();
out.write("hello".getBytes());
// 接收服務器反饋
InputStream in = sc.getInputStream();
byte[] bys = new byte[1024];
int len=120;
while (in.read(bys)!=-1) {
System.out.println("客戶端接收的數據:" + new String(bys, 0, len));
}
// len = in.read(bys);
// System.out.println("客戶端接收的數據:" + new String(bys, 0, len));
sc.close();
}
}
服務端代碼:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpReceive {
public static void main(String[] args) throws IOException {
// 創建服務器端的ServerSocket對象(ServerSocket類)
ServerSocket sc = new ServerSocket(11223);
// 監聽客戶端連接,創建一個監聽套接字(返回一個Socket對象)
Socket ac = sc.accept();
// 獲取輸入流,讀數據
InputStream in = ac.getInputStream();
byte[] bys = new byte[1024];
int len;
while ((len = in.read(bys))!=-1) {
System.out.println("數據是:"+ new String(bys, 0, len));
}
// len = in.read(bys);
// System.out.println("數據是:" + new String(bys, 0, len));
// 發送客戶端,進行反饋
OutputStream out = ac.getOutputStream();
out.write("我收到數據了".getBytes());
// 釋放資源
sc.close();
}
}
主要原因:
通過查看api文檔關於read(byte[] b)的介紹,從輸入流讀取一些字節數,並將它們存儲到緩沖區b。實際讀取的字節數作為整數返回。
該方法阻塞直到1.輸入數據可用;2.檢測到文件結束;3.拋出異常。
也就是說在上述幾種情況下這個方法是一直阻塞的,所以當服務端和客戶端都使用while循環的時候,無法判斷socket的輸入流中啥時候結束導致一直死循環。
解決上述問題:
經查詢資料了解Socket對象的shutdownOutput()方法(描述:禁用此套接字的輸出流。對於TCP套接字,任何先前寫入的數據將被發送,
隨后是TCP的正常連接終止序列),可用來對輸出流增加結束標識,這樣輸入流通過read方法讀數據時就能檢測到文件結束而終止,不會出現一直阻塞情況。
如圖,在客戶端和服務端的輸出流代碼后調用Socket對象的shutdownOutput的方法即可

如圖,在客戶端和服務端的輸出流代碼后調用Socket對象的