2012-05-10 29 views
5

Mam bardzo irytujący problem, który znalazłem kilka razy na innych forach, ale nie mogę znaleźć odpowiedniego rozwiązania. Problem polega na tym, że recv() zwraca 0 w ostatnich kilku bajtach połączenia. Oto kilka podstawowych informacji.recv() zwraca 0

  • Obie aplikacje (klient/serwer) działają na tym samym komputerze.
  • Oba gniazda (klient/serwer) nie są blokowane.
  • Przesyłany rozmiar danych wynosi 53 bajty.
  • Zarówno zamknięcie połączenia (klient/serwer), jak i zamknięcie, gdy wykonano ostatnie polecenie send()/recv().
  • Próbowałem też z SO_LINGER i 10 sekund, bez powodzenia obu

nazywam send() kilka razy (małe kawałki), a od strony klienta 53 bajtów transmitowanych. Serwer wywołuje recv() kilka razy (4 bajtowe żądania) i czyta 49 bajtów, a następnie zwraca 0 (54 Bajty - 49 bajtów, więc brakuje 4 bajtów).

MSDN i niektóre fora pisać dla non-blocking gniazdach:

  • recv() zdecydowanie zwraca < 0 w przypadku błędu i errno/WSAGetLastError jest ustawiony
  • recv() zdecydowanie powraca = 0 gdy druga strona zamknął połączenie
  • recv() zdecydowanie zwraca> 0 gdy dane odczytywano

MSDN mówi:

Korzystanie z funkcji zamykania gniazd lub zamykania przy pomocy SD_SEND lub SD_BOTH powoduje wysłanie sygnału RELEASE do kanału sterowania. Z powodu do korzystania z oddzielnych kanałów sygnałowych i transmisji danych przez ATM, możliwe jest, że sygnał RELEASE dotrze do zdalnego końca, zanim ostatnie dane z dotrą do miejsca docelowego, powodując utratę tych danych. Jednym z możliwych rozwiązań jest zaprogramowanie wystarczającego opóźnienia między wysłanymi ostatnimi danymi , a funkcją zamykania gniazd lub wyłączania wywołania gniazda ATM .

ta jest uważana w przykładzie recv() i send(): http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx

Ale jeszcze nie sukces, nadal trochę przerwań w 10% wszystkich połączeń po otrzymaniu 49 Byte, 90 % połączeń zakończy się pomyślnie. Jakieś pomysły? Dzięki.

+0

Podejrzewam robicie jeden z kilku klasycznych błędów programistycznych gniazdo.Mam kilka pomysłów, ale wolę najpierw zobaczyć kod, zanim coś napiszesz. – selbie

Odpowiedz

9

recv() zwraca 0 tylko wtedy, gdy zażądasz bufora 0-bajtowego lub drugi węzeł równo rozłącza się. Jeśli nie otrzymujesz wszystkich oczekiwanych danych, nie czytasz poprawnie danych na samym początku. Zaktualizuj swoje pytanie za pomocą rzeczywistego kodu.