免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

用Socket做一個通訊項目的一點(diǎn)心得

 dddTTLee 2011-04-18
 
 
最近做了一個小型的通訊項目,有一點(diǎn)體會,在這里拿來和大家分享一下:

一:關(guān)于Socket的長連接
這個項目中,客戶提出了“一次連接,10次交互”的需求,就是說創(chuàng)建一個Socket后,在客戶端與服務(wù)端完成10次交互前(客戶端請求,服務(wù)端響應(yīng)算一次交互),不會被關(guān)掉。起初按照這種思路來做Socket的長連接,發(fā)現(xiàn)在使用阻塞IO的情況下,如果,在一次交互后不關(guān)閉Socket,那么下次客戶端雖然可以正常發(fā)送請求,但是怎么也讀不出服務(wù)端的響應(yīng)信息,因為服務(wù)端的輸入流被阻塞在上次讀取后。如果,每次交互后都關(guān)掉Socket,就不符合客戶的要求了。于是查資料,說是用異步輸入輸出流java.nio,于是將其引入項目中,結(jié)果發(fā)現(xiàn),異步IO雖然為多個Socket提供了不同的通道,但是對一個Socket而言,依然存在上述問題。于是和客戶溝通,客戶問一技術(shù)牛人,結(jié)果得到“Socket長連接指的是服務(wù)端將消息往客戶端推, 就是在一次連接下,客戶端向服務(wù)端發(fā)多條消息, 服務(wù)端一次響應(yīng)完畢,其間,客戶端如果在一定的時間內(nèi)沒有消息發(fā)往服務(wù)端,服務(wù)端會主動斷開連接”。

二:關(guān)于Socket使用中讀取響應(yīng)消息的方法
使用Socket進(jìn)行通信會涉及到讀取服務(wù)端的響應(yīng)消息。讀取的方法可分為2類三種。

類1:一次性全部讀取。

代碼:
方法一:public String getResultStr(Socket sourceSocket)
{

String resultStr = null;

InputStream in;
try {
in = sourceSocket.getInputStream();
int readIndex = 5 * 1024 * 1024;
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in), readIndex);
char[] charArray = new char[readIndex];
int read_rst = bufferedReader.read(charArray);
resultStr = new String(charArray, 0, read_rst);
bufferedReader.close();

} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}
類2:非一次性讀取

方法二:一行行讀
public String getResultStr(Socket sourceSocket)
{
String resultStr = null;

InputStream in;

try {
in = sourceSocket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
StringBuffer responseBuffer = new StringBuffer();
String line = bufferedReader.readLine();
while (null != line)
{
responseBuffer.append(line);
line = bufferedReader.readLine();
}

bufferedReader.close();

resultStr = responseBuffer.toString();

} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}

方法三:一字節(jié)一字節(jié)讀
public String getResultStr(Socket sourceSocket)
{
String resultStr = null;

InputStream in = null;

try {
in = sourceSocket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));

int read_rst = bufferedReader.read();

StringBuffer readBuffer = new StringBuffer();
while (-1 != read_rst)
{
char singleChar = (char) read_rst;

readBuffer.append(singleChar);
}

bufferedReader.close();

resultStr = readBuffer.toString();
} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}

其中方法一的優(yōu)點(diǎn)是讀取速度快,且不用被超時所擾。缺陷是,只能讀取一定量的字節(jié),雖然BufferedReader的構(gòu)造方法提供了設(shè)置緩沖區(qū)大小的功能,但是不管設(shè)多大,都只能讀取一定量的字節(jié),據(jù)項目中的情況來看,是65536個。如果響應(yīng)消息有幾MB的話,這種方法是肯定不行的。但是如果讀取的消息很小,在65536個字節(jié)以內(nèi),則可以使用。

方法二的優(yōu)點(diǎn)是便于做讀取后的算法操作,速度嘛也挺快。缺陷是不能精確讀取。因為readLine的方法讀不出’\n’,’\r\n’,所以讀出來的內(nèi)容其長度與實際長度有出入。

方法三是最優(yōu)解。(以上只是三種方法的原型,具體業(yè)務(wù)還要具體實現(xiàn))


三:關(guān)于解決Socket讀取響應(yīng)消息超時的分析及解決方法:

分析
在使用Socket的過程中會遇到讀取響應(yīng)消息超時的問題,這是為什么呢?就我現(xiàn)在的理解,一句話:在服務(wù)端還沒有關(guān)閉連接前,客戶端讀取響應(yīng)消息就會一直等待,直到超時。

解決方法:
1.Socket提供的setSoTimeout(int timeout) 方法
在獲得Socket的實例后,設(shè)置下超時時間,然后當(dāng)read或是readLine完最后一個字節(jié)或是字符串后,會拋一個InterruptedIOException,在catch里做你想做的事情,或break,或關(guān)掉連接。

2.如果服務(wù)端也是你設(shè)計的話(就是響應(yīng)消息也是你拼接的),請看。
可以在服務(wù)端里拼接響應(yīng)消息的方法里為響應(yīng)消息加上一個‘\r\n‘,注意一定要加在消息末尾。然后用“二:關(guān)于Socket使用中讀取響應(yīng)消息的方法”里第三種方法來讀取響應(yīng)消息,注意,通信消息頭中肯定會有“Content-Length“一項,先取出其值(Content-Length表示消息主體的字節(jié)長度),接著找出主體消息的起始位置(主體消息中的最前方一定要是個固定的內(nèi)容),開始計算響應(yīng)消息的實際字節(jié)長度,最后將取出的Content-Length的值與實際計算出的長度進(jìn)行比較,如果相等就break掉,這樣,就不會讀到會引起超時消息末尾。

其方法1的優(yōu)點(diǎn)時易于實現(xiàn),缺陷是不安定因素太大。setSoTimeout里總要設(shè)個值,設(shè)多少呢?假設(shè)在網(wǎng)絡(luò)正常情況下讀一個1MB的響應(yīng)消息需要1s,那么如果網(wǎng)絡(luò)阻塞呢?如果你設(shè)一個很大的值,就會影響使用。
方法2的優(yōu)點(diǎn)是不受網(wǎng)絡(luò)因素的影響。缺陷是,如果服務(wù)端的中文字符編碼與流中的中文字符編碼不一致,會導(dǎo)致亂碼,進(jìn)而會影響計算的準(zhǔn)確度。一旦計算的不準(zhǔn),就會超時。
不過,方法2仍是最優(yōu)解。

以上就是自己對這個項目的一點(diǎn)體會,歡迎大家指正。
 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多