2013-07-29 5 views
1

이것은 우분투 12.04에서 발생합니다. 동일한 코드가 OSX에서 잘 작동합니다.몇백 바이트 만 보내면 EAGAIN으로 send()가 실패합니다.

아래의 로그에서 SO_SNDBUF가 20440이고 EAGAIN으로 실패하기 전에 여러 send()가 성공한 것을 볼 수 있습니다.

wsmux started on port 8888 
send buffer size = 20440 
open wsmux:187.59.165.86-16580 
send 129, result 129, errno 115 
message wsmux:187.59.165.86-16580 NICK zxc5239 
message wsmux:187.59.165.86-16580 USER zxc zxc zxc zxc 
message wsmux:187.59.165.86-16580 JOIN #a 
send 2, result 2, errno 115 
send 66, result 66, errno 115 
send 2, result 2, errno 115 
send 42, result 42, errno 115 
send 2, result 2, errno 115 
send 100, result 100, errno 115 
send 2, result 2, errno 115 
send 43, result 43, errno 115 
send 2, result 2, errno 115 
send 48, result 48, errno 115 
send 2, result -1, errno 11 
close wsmux:187.59.165.86-16580 Resource temporarily unavailable 

유일한 소켓 옵션은 TCP_NODELAY 및 O_NONBLOCK입니다. 여기에 무슨 문제가있을 수 있습니까?

문제의 코드 : 당신이 O_NONBLOCK이있는 경우 비 블로킹 소켓을 설정하기 때문에

+0

로그에 쓰기 작업이 전혀 표시되지 않습니다. 처음 실패하기 전에 얼마나 많은 데이터가 성공적으로 전송됩니까? –

+0

getsockopt (SO_SNDBUF)가 거짓이 아닌 한 @JoachimIsaksson 300 바이트는 20440 바이트 송신 버퍼에 맞을 것입니다. – lzm

+0

원격 끝 (두 번째 블록의 10 패킷)에서 모든 것이 올바르게 수신되었습니다. – lzm

답변

0

다음 sendrecv에 대한 모든 호출이, EAGAIN와 함께 실패 할 수 있습니다 (이것은 통화가 차단된다는 것을 의미합니다). 오류가 아니며 하나로 처리되어서는 안됩니다. 예를 들어 man 페이지에서 명시 적으로 설명되어 있습니다. send.

+0

예. 문제는 몇 백 바이트가 지나면 왜 실패 할까? 분명히 버퍼에 충분한 공간이 남아 있습니다. – lzm

+0

커널이 전체 메시지를 전송하지 못하게 할 수 있습니다. 당신이이 상황을 다루어야하는 어떤 방법이든 상관 없습니다. – zoska

0

TCP_NODELAYsend은 모든 TCP/IP 헤더와 함께 즉시 데이터를 전송합니다. 매 2- 바이트 패킷마다이를 계속 수행하는 경우 원격 엔드가 새 패킷을 전송하기 전에 ACK 패킷을 가지고 있기 때문에 EAGAIN으로 빠르게 실행됩니다. 말할 것도없이 매우 비효율적입니다! 2 바이트 패킷이 정말로 긴급한가요?