winsock bind zwraca 10048

0

Witam,

jest to mój pierwszy post na tym forum. Dodam iż jestem początkujący więc proszę o wyrozumiałość jeśli piszę jakieś głupoty.

Sprawa wygląda tak:

Thread1 uruchamia nasłuch na porcie 27015
Thread2 uruchamia nasłuch na porcie 27016
Thread3 sprawdza w pętli czy 1 i 2 działają, jeżeli nie (nie działa nasłuch oraz nie ma aktualnie podłączonego użytkownika) podnosi dany wątek

Wygląda to następująco

  1. Gdy uruchomię program-serwer z nasłuchem na tylko jednym porcie, po rozłączeniu klienta wszystko się podnosi i wznawiany jest nasłuch.
  2. Gdy jednak 2 porty nasłuchują, podłączy i rozłączy się klient na jednym porcie, próba wznowienia nasłuchu zwraca na bindzie błąd 10048 address already in use
  3. podczas gdy 2) zwraca non stop 10048, łączy się klient na drugim nasłuchującym porcie, po czym rozłącza i wtedy Thread3 bez problemu podnosi obydwa wątki

W obydwu przypadkach, rozłączenie klienta wywołuje te same polecenia czyli CloseSocket, WSACleanup i _endthread.
W task managerze widać iż wątki są zamykane i otwierane na nowo.

Nie wiem dokładnie jak działa WSACleanup (The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll) w momencie, gdy go wywołuję przy jednoczesnym nasłuchiwaniu na drugim porcie. Czy wówczas nie czyści on wszystkiego co pozostało po pierwszym wątku?

Z góry dziękuję za pomoc.
Michał

0

Bez kawalka kodu ciężko coś powiedzieć... Szklana kula w naprawie...

0

Chyba się wyjaśniło

There must be a call to WSACleanup for each successful call to WSAStartup. Only the final WSACleanup function call performs the actual cleanup. The preceding calls simply decrement an internal reference count in the WS2_32.DLL.

Wywołując 2x WSACleanup() przy rozłączeniu pierwszego klienta ponowne bindowanie dla zwolnionego portu się powiodło.
To niestety prowadzi do rozłączenia drugiego klienta jeśli ten był również połączony.

Sockets that were open when WSACleanup was called are reset and automatically deallocated as if closesocket were called.

Pytanie sprowadza się do tego jak zwolnić użyty port aby można było go ponownie zbindować pozostawiając pozostałe porty nienaruszone?

0

Wywołując 2x WSACleanup() przy rozłączeniu pierwszego klienta ponowne bindowanie dla zwolnionego portu się powiodło.

Eee?

W całym programie powinno być jedno WSAStartup i jedno WSACleanup. Na przykład w funkcji main.

0

W całym programie powinno być jedno WSAStartup i jedno WSACleanup. Na przykład w funkcji main.

Dziękuję za informację ale nawet jeśli, to nie rozwiązuje to niestety problemu z brakiem możliwości ponownego zbindowania na wcześniej użytym porcie.
Wciąż, aby zbindować socket z tym samym portem po wcześniejszym rozłączeniu z niego, wymagane jest wywołanie WSACleanup.
A w przypadku pojedynczego wywołania WSAStartup, ubija on wszystkie inne porty które sobie nasłuchują.

1

Normalnie nie trzeba ponownie bindować portu. Do czego ci to potrzebne?

0

Normalnie nie trzeba ponownie bindować portu. Do czego ci to potrzebne?

I o to chodzilo dziękuję! Wrzuciłem inicnalizację i bindowanie na starcie apki.
Dodatkowo mój problem polegał też na przypisywaniu socketu nasłuchującego do socketu zwracanego z accept. Zamiast tego socket nasłuchujący zostawiłem w spokoju a cały transfer idzie po acceptsocket. Bez tej zmiany otrzymywałem błąd z listen().

Teraz po rozłączeniu klienta po prostu wznawiam nasłuch na tym sockecie bez wrześniejszego jego zamykania stąd faktycznie żaden bind nie jest potrzebny.
Jeszcze raz dziękuję za podpowiedź i wyprowadzenie mnie z błędu ;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1