日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java socket 阻塞模式_Java中Socket Read阻塞问题

發布時間:2025/3/12 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java socket 阻塞模式_Java中Socket Read阻塞问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本人來說并不熟悉JAVA語言,只是近期在分析某個簡單的java agent程序時,根據對應的代碼寫了一個對接的程序,兩者之間是典型的C/S socket編程。客戶端在向服務端發送相應的指令后,服務端(裝agent的主機)執行后會返回執行的數據給客戶端。在直接一行行收取數據時是正常的,但通過while循環時會卡住。

一、java讀取數據的兩種方式

從Socket上讀取對端發過來的數據一般有兩種方法:一種是按字節,一種是按字符。

1、按照字節流讀取

BufferedInputStream in = new BufferedInputStream(socket.getInputStream());

int r = -1;

List l = new LinkedList();

while ((r = in.read()) != -1) {

l.add(Byte.valueOf((byte) r));

}

2、按照字符流讀取

readLine()方法在進行讀取一行時,只有遇到回車(\r)或者換行符(\n)才會返回讀取結果,這就是“讀取一行的意思”。如果不指定buffer大小,則readLine()使用的buffer有8192個字符。在達到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才會返回。BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

String s;

while ((s = in.readLine()) != null) {

System.out.println("Reveived: " + s);

}

read()和readLine()都會讀取對端發送過來的數據,如果不加while循環時,是不會存在異常阻塞的情況的。但在使用while后,如果無數據可讀,就會阻塞直到有數據可讀。或者到達流的末尾,這個時候分別返回-1和null。具體也可以參看segmentfault上別人的提問和回答。

使用while的好處就是對于返回數據較多的情況,比較方便,如果是直接readLine而不加while時,默認只能取得最后一行的數據;其壞處也顯而易見----阻塞等待。

二、異常處理

1、服務端處理

發送完后調用Socket的shutdownOutput()方法關閉輸出流,這樣對端的輸入流上的read操作就會返回-1。注意不能調用socket.getInputStream().close()。這樣會導致socket被關閉。當然如果不需要繼續在socket上進行讀操作,也可以直接關閉socket。但是這個方法不能用于通信雙方需要多次交互的情況。

2、客戶端處理

為了防止read操作造成程序永久掛起,還可以給socket設置超時。例如下面的方法設定超時3秒:

socket.setSoTimeout(3000)

如果read()方法在設置時間內沒有讀取到數據,就會拋出一個java.net.SocketTimeoutException異常。

3、雙方約定

發送數據時,約定數據的首部固定字節數為數據長度。這樣讀取到這個長度的數據后,就不繼續調用read方法。或者雙方約定結尾字符信息,在讀取到相應信息時,客戶端主動發送斷開連接的信息,或者發送信號給服務端,由服務端斷開連接。

三、其他

我在實際使用中,使用了上面異常處理中提到的第三種。但在應用中如果由客戶端進行超進異常斷開連接時,客戶端在接收數據過程中會收到異常信息如下:

這時候就需要使用try……catch(Exception e)語句進行異常捕獲處理。最終一個完整的客戶端請求如下:

import java.io.*;

import java.net.*;

public class TalkClient {

public static void main(String args[]) {

try{

Socket socket=new Socket("127.0.0.1",4700);

//向本機的4700端口發出客戶請求

BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));

//由系統標準輸入設備構造BufferedReader對象

PrintWriter os=new PrintWriter(socket.getOutputStream());

//由Socket對象得到輸出流,并構造PrintWriter對象

BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

//由Socket對象得到輸入流,并構造相應的BufferedReader對象

String readline;

readline=sin.readLine(); //從系統標準輸入讀入一字符串

while(!readline.equals("bye")){

//若從標準輸入讀入的字符串為 "bye"則停止循環

os.println(readline);

//將從系統標準輸入讀入的字符串輸出到Server

os.flush();

//刷新輸出流,使Server馬上收到該字符串

System.out.println("Client:"+readline);

//在系統標準輸出上打印讀入的字符串

System.out.println("Server:"+is.readLine());

//從Server讀入一字符串,并打印到標準輸出上

readline=sin.readLine(); //從系統標準輸入讀入一字符串

} //繼續循環

os.close(); //關閉Socket輸出流

is.close(); //關閉Socket輸入流

socket.close(); //關閉Socket

}catch(Exception e) {

System.out.println("Error"+e); //出錯,則打印出錯信息

}

}

}

總結

以上是生活随笔為你收集整理的java socket 阻塞模式_Java中Socket Read阻塞问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。