2010-04-27 4 views
2

Java NIO의 SocketChannel을 사용하여 쓰기 : int n = socketChannel.write(byteBuffer); 대부분의 경우 데이터는 한 두 부분으로 전송됩니다. 즉, 데이터가 하나의 시도로 전송 될 수없는 경우, 나머지 데이터가 재 시도된다.Java NIO SocketChannel 쓰기 문제

여기에서 문제는 데이터가 한 번에 완전히 전송되지 않고 데이터를 여러 번 보내려고 할 때 여러 번 시도한 후에도 하나의 문자가 기록되지 않는 경우입니다. 채널, 마지막으로 잠시 후 remaning 데이터가 전송됩니다. 이 데이터는 크지 않을 수 있으며 약 2000 자일 수 있습니다.

이러한 문제의 원인은 무엇입니까? RAM, OS 등과 같은 외부 요인으로 인해 장애가 발생할 수 있습니까?

이 문제를 해결할 수 있도록 도와주세요. 다른 정보가 필요하면 알려주십시오. 감사

편집

: 채널이 실제 쓰기 전에 쓸 수있는 데이터를 제공 할 수 있다면

는 NIO SocketChannel에있는 방법이 있나요은 확인합니다. 여기서 완전한 데이터를 쓰려고 시도한 후에 일부 데이터가 채널에 기록되지 않은 경우 나머지 데이터를 쓰기 전에 SocketChannel이 더 많은 데이터를 가져올 수 있는지 여부를 확인할 수 있습니다. 따라서 무의식적으로 여러 번 시도하는 대신이 데이터를 작성하는 스레드가 기다리거나 다른 작업을 수행 할 수 있습니다.

+0

코드를 게시 할 수 있습니까? –

답변

1

TCP/IP는 스트리밍 프로토콜입니다. 어떤 레벨에서든 보내는 데이터가 싱글 바이트 세그먼트 나 그 세그먼트와 하나의 세그먼트 사이에 흩어지지 않을 것이라는 보장은 없습니다.

기대치가 잘못되었습니다.

EDIT에서 소켓 보내기 버퍼가 채워지면 write()가 0을 반환합니다. 당신이 그것을 얻을 때, OP_WRITE에 대한 채널을 등록하고 쓰기 루프를 중지하십시오. OP_WRITE를 얻으면 등록 취소 (매우 중요)하고 계속 작성하십시오. write()가 0을 다시 반환하면 반복하십시오.

1

TCP를 사용하는 동안 소켓 버퍼가 채워질 때까지만 송신 측 소켓 채널에 쓸 수 있습니다. 따라서 수신기가 데이터를 소비하는 속도가 느린 경우 송신 측 소켓 버퍼가 가득 차고 앞에서 설명한 것처럼 write()가 0을 반환 할 수 있습니다.

송신자 측에서 보낼 데이터가있는 경우 OP_WRITE가 관심있는 작업으로 SocketChannel을 등록해야하며 선택기가 SelectionKey를 반환하면 key.isWritable()을 확인한 다음 그 채널에 글쓰기. 위의 Nilesh에서 언급했듯이 완전한 데이터를 작성한 후 OP_WRITE 비트를 셀렉터와 함께 등록 취소하는 것을 잊지 마십시오.

관련 문제