Tomcat에서 메시지를 보내고 받기 위해 원격 서버에 SocketChannel을 만들었습니다. 원격 컴퓨터에서 메시지를 받으려면 작업 전용 스레드를 사용했습니다 (이 스레드는 소켓에서 읽는 것 외에는 아무것도 읽지 않습니다).Java SocketChannel 내 바이트를 먹는 중
일부 바이트가 SocketChannel에서 수신되면 (새 데이터에 대해 비 차단 모드로 SocketChannel을 폴링 함) 다음 메시지의 길이를 얻기 위해 4 바이트를 읽은 다음, 다음 바이트를 할당하고 읽습니다. SocketChannel은 디코딩되어 메시지로 재구성됩니다.
다음은 수신 스레드에 대한 내 코드입니다 : 나는에 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에서 읽을 때 소켓은 약 100 바이트를 건너 뜁니다. 이로 인해 잘못된 바이트가 읽히고 길이가 해석되어 모든 내용이 손상됩니다.
코드에 어떤 문제가 있습니까? 다른 스레드가 SocketChannel에서 읽는 중입니다.
헤더 버퍼를 4 바이트의 arry로 변환하는 대신 getInt()를 호출하여 길이를 읽을 수 있습니다. 이것을 부호없는 int로 처리하려면 항상 0xFFFFFFFF의 long 및 bitwise AND로 변환 할 수 있습니다. 또한, – Adamski
자바가 작은 엔디안으로 바이트 []의 arr [4]를 읽는지 확신 할 수 없지만 아마 할 수 있습니다. 어쨌든, 나는 이것이 문제의 원인이라고 의심합니다. 첫 번째 메시지 길이가 정확하며 그 바이트 수를 읽습니다. 읽은 메시지를 검사해도 오류가 없음을 알 수 있습니다. 헤더의 다음 4 바이트를 읽으려고 할 때만 문제가 있습니다. – futureelite7