我創建了一個SocketChannel到遠程服務器在Tomcat上發送和接收消息。爲了接收來自遠程計算機的消息,我使用了專用於任務的線程(只有此線程纔會從套接字讀取,沒有其他)。Java的一個SocketChannel吃我的字節
當在SocketChannel接收到一些字節時(我繼續在非阻塞模式下爲新數據輪詢SocketChannel),我首先讀取4個字節來獲取下一個消息的長度,然後分配和讀取x字節SocketChannel,然後解碼並重構成消息。
下面是我的接收線程代碼:
@Override
public void run() {
while (true) { //Don't exit thread
//Attempt to read the size of the incoming message
ByteBuffer buf = ByteBuffer.allocate(4);
int bytesread = 0;
try {
while (buf.remaining() > 0) {
bytesread = schannel.read(buf);
if (bytesread == -1) { //Socket was terminated
}
if (quitthread) break;
}
} catch (IOException ex) {
}
if (buf.remaining() == 0) {
//Read the header
byte[] header = buf.array();
int msgsize = (0xFF & (int)header[0]) + ((0xFF & (int)header[1]) << 8)
+ ((0xFF & (int)header[2]) << 16) + ((0xFF & (int)header[3]) << 24);
//Read the message coming from the pipeline
buf = ByteBuffer.allocate(msgsize);
try {
while (buf.remaining() > 0) {
bytesread = schannel.read(buf);
if (bytesread == -1) { //Socket was terminated
}
if (quitthread) break;
}
} catch (IOException ex) {
}
parent.recvMessage(buf.array());
}
if (quitthread) {
break;
}
}
}
我從接收的SocketChannel第一字節是好的,我成功地解碼該消息。然而,下次我從SocketChannel讀取時,套接字跳過了大約100個字節,導致錯誤的字節被讀取並解釋爲長度,導致一切損壞。
代碼有什麼問題?沒有其他線程正在讀取SocketChannel。
您可以簡單地調用getInt()來讀取長度,而不是將頭緩衝區轉換爲4字節的長度。如果你想把它當作一個無符號整數,你總是可以用0xFFFFFFFF進行長整型AND運算。另外, – Adamski 2009-11-16 17:02:20
我可能可以,但我不確定java是否會像byte endian那樣讀取byte []的arr [4]。 無論如何,我懷疑這是問題的原因。第一個消息長度是正確的,我讀了這個字節數。檢查讀取的消息也表明沒有錯誤。當我嘗試讀取頭的下4個字節時,只有一個問題。 – futureelite7 2009-11-16 17:06:37