程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> 服務器-關於建立一個TCP服務端出現阻塞問題

服務器-關於建立一個TCP服務端出現阻塞問題

編輯:編程解疑
關於建立一個TCP服務端出現阻塞問題

這裡是tcp客戶端的代碼


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Socket_client {

public static void main(String[] args) throws UnknownHostException, IOException {
    //first,創建一個socket對象
    Socket s = new Socket("192.168.1.107",20000);

    //second,獲取Socket中的輸出流
    OutputStream out = s.getOutputStream();

    //third,發送信息
    out.write("嘿嘿嘿".getBytes());


    //添加讀取服務器返回信息功能
    //使用socket流讀取服務器返回數據
    InputStream in = s.getInputStream();
    byte[] b = new byte[1024];
    int len = in.read(b);
    String str = new String(b,0,len);
    System.out.println(str);

    //關閉資源
    s.close();

}

}


這裡是tcp服務端的代碼


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_Socket {
public static void main(String[] agrs) throws IOException{
//先建立一個服務Socket
ServerSocket ss = new ServerSocket(20000);

    //獲取客戶Socket對象
    Socket s = ss.accept();

    //使用客戶的Socket對象將信息打印出來
    InputStream in = s.getInputStream();
    byte[] b = new byte[1024];
    int len;
    while((len = in.read(b))!=-1){    //問題就出在這裡,用循環讀取,讀取-1時,出現阻塞,後面代碼無法運行
        String str = new String(b,0,len);
        System.out.println(str);
    }

    //使用客戶的Socket對象將成功接受信息的信息反饋給客戶端
    OutputStream out = s.getOutputStream();
    out.write("成功接受到信息".getBytes());

    //關閉資源
    s.close();
    ss.close();
}

}
先執行了服務端,然後再執行客戶端,服務端收到客戶端發來的string後阻塞了,客戶端也阻塞了,無法接受服務端回復的string
如果我把服務端循壞代碼改成如下:

//使用客戶的Socket對象將信息打印出來
InputStream in = s.getInputStream();
byte[] b = new byte[1024];
int len = in.read(b);
String str = new String(b,0,len);
System.out.println(str);
--------------------------------------------------
程序能正常運行,為何,求解?

最佳回答:


這個問題本人已經解決了,一直沒時間,現在寫一下。為什麼 while((len=in.read(b))!=-1) 會阻塞呢?這是因為read()在讀的時候沒有讀到結束符,
也就是說從socket的輸入流中沒有獲取到結束標記,所以一直在等待著客戶端繼續發送字節,然而客戶端已經發送完畢,進行到 “使用socket流讀取服務器返回數據”
這一步,這時,客戶端這邊的read()開始等待服務端返回的字節,因此,兩邊就陷入互相等待的狀況!!!
解決辦法:在客戶端
//third,發送信息
out.write("嘿嘿嘿".getBytes());
//在這一步後面,再加一句作用是加入socket流的結束標志,但並不是關閉流資源,告訴服務端,數據發送完畢,讓服務器停止讀取
s.shutdownOutput();

PS:其實shutdownOutput()這個方法相當於服務端的while((len=in.read())!=null){..........省略; 加入 if(in.read()=="end"){break}},當接受到結束標記“end”的時候就
跳出循環了,或者理解為傳入了一個null,就跳出循環。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved