2011-12-19 7 views
2

나는 C/S 프로그램이 있습니다. 클라이언트가 소켓을 사용하여 서버에 파일을 보내면 대략 700k 데이터를 보내고 클라이언트 (win7)는 소켓 10054 오류를 수신합니다. 이는 연결 재설정을 의미합니다.소켓 오류 10054

Server는 CentOS 5.4에서 작동하며 클라이언트는 가상 박스에서 실행되는 windows7 가상 머신입니다. 클라이언트와 서버는 가상 네트워크 인터페이스를 통해 통신합니다. 명령 포트 (로그 전송)는 정상이지만 데이터 포트 (파일 전송)에 문제가 있습니다. 소켓 버퍼 크기가 잘못되었거나 다른 이유로 인해 발생 했습니까? 누구든지 문제를 확인하는 데 도움을 줄 수 있다면. 감사.

내가 소켓 호출 할 때마다 버퍼가 4096 바이트 전송 (소켓 버퍼, 4096, 0)

CentOS는 소켓 설정을 동일 보냅니다.

#sysctl -a 
... 
net.ipv4.tcp_rmem = 4096  87380 4194304 
net.ipv4.tcp_wmem = 4096  16384 4194304 
net.ipv4.tcp_mem = 196608  262144 393216 
net.ipv4.tcp_dsack = 1 
net.ipv4.tcp_ecn = 0 
net.ipv4.tcp_reordering = 3 
net.ipv4.tcp_fack = 1 

불완전한 결과 문제가 발생할 경우 소켓 버퍼 구성이 의미하는 바를 잘 모르겠습니다.

+0

"상대방에 의한 연결 재설정"의 가장 큰 원인은 다른 쪽 충돌하는 프로그램입니다. –

+0

@David Schwartz, 서버 솔기가 정상이며 소켓이 닫히지 않았습니다. 마지막으로 recv 시간 초과 오류가 발생했습니다. –

+0

* 수신 * 시간 초과? TCP는 일반적으로 수신 시간 초과가 없습니다. 그게 당신의 코드인가요? 수신 시간이 초과되었다고 생각하면 어떻게합니까?그리고 ** 서버가 수신 제한 시간을 갖기 전에 클라이언트가 ** 피어에 의한 연결 재설정을 확신했는지 100 % 확신합니까? (다른 방법이 있다면 코드의 버그입니다. 각 측은 다른 측을 기다리고 있습니다.) –

답변

4

거의 확실하게 코드에 버그가 있습니다. 대부분 한 쪽에서는 상대방이 시간 초과되어 연결이 비정상적으로 닫힌다 고 생각합니다. 이것이 데이터를 얻기 위해 수신 함수를 호출하는 가장 일반적인 방법이지만 실제로 데이터를 얻었지만 실제로는 깨닫지 못했습니다. 따라서 이미받은 데이터를 기다리고 있으므로 시간이 초과됩니다.

예 :

1) 클라이언트가 메시지를 보냅니다.

2) 클라이언트가 다른 메시지를 보냅니다.

3) 서버는 두 메시지를 모두 읽지 만 인식 만한다고 생각합니다.

4) 클라이언트는 확인 응답을 수신하고 서버가 보내지 않을 두 번째 응답을 기다립니다.

5) 서버는 실제로 수신 한 두 번째 메시지를 기다립니다.

이제 서버가 클라이언트를 기다리고 있으며 클라이언트가 서버를 기다리고 있습니다. 서버가 잘못 코딩되어 실제로 한 번에 두 개의 메시지가 있다는 것을 알지 못했습니다. TCP는 메시지 경계를 보존하지 않습니다.

귀하의 프로토콜에 대해 자세히 알려 주시면, 무엇이 잘못되었는지 자세히 설명해 드릴 수 있습니다. 무엇이 메시지를 구성합니까? 어느 쪽이 언제 보낼까요? 승인이 있습니까? 등등.

그러나 짧은 버전은 각면이 다른 쪽을 기다리는 것입니다.

대부분의 경우 피어에 의한 연결 재설정이 증상 일 수 있습니다. 문제가 발생하면 한 쪽 시간 초과되어 연결이 중단됩니다. 다른 쪽이 연결을 중단했기 때문에 다른 쪽에서 연결 재설정을 가져옵니다.

+0

socksetopt를 사용하여 recv timeout을 설정합니다. 시간 제한을 설정하지 않으면 프로그램 서버는 recv를 영원히 기다리고 recv는 반환하지 않습니다. –

+0

아, 그러면 실제로받은 메시지를 기다리는 데'recv'를 호출 할 것입니다. 어느 쪽이든 아니면 시간 초과로 충분하지 않습니다. 또는 귀하의 프로토콜이 올바르게 구현되지 않았으며 상대방이 메시지를 보낼 이유가 없을 때 메시지를 기다리는 중입니다. 하지만 내 내기는 수신 시간이 초과되고 연결이 재설정됩니다. 문제는 타임 아웃이며 리셋은 증상입니다. –

+0

아마도이 문제는 내 코드에서 수신 버퍼 처리와 관련이 있습니다. 확인해 보겠습니다. –