Windows Sockets: blokowanie
W tym artykule i dwóch artykułach towarzyszących opisano kilka problemów z programowaniem windows Sockets. W tym artykule opisano blokowanie. Inne problemy zostały omówione w artykułach: Windows Sockets: Byte Ordering and Windows Sockets: Converting Strings (Gniazda systemu Windows: konwertowanie ciągów).
Jeśli używasz lub pochodzisz z klasy CAsyncSocket, musisz samodzielnie zarządzać tymi problemami. Jeśli używasz lub pochodzisz z klasy CSocket, MFC zarządza nimi za Ciebie.
blokowanie
Gniazdo może być w trybie "blokującym" lub "trybie blokującym". Funkcje gniazd w trybie blokującym (lub synchronicznym) nie są zwracane, dopóki nie zakończą akcji. Jest to nazywane blokowaniem, ponieważ gniazdo, którego funkcja została wywołana, nie może nic zrobić — jest blokowane — dopóki wywołanie nie zostanie zwrócone. Wywołanie funkcji składowej Receive
może zająć na przykład dowolnie długi czas, ponieważ oczekuje na wysłanie aplikacji wysyłającej (jest to, jeśli używasz CSocket
metody lub z CAsyncSocket
blokowaniem). CAsyncSocket
Jeśli obiekt jest w trybie nieblokowania (działa asynchronicznie), wywołanie zwraca natychmiast i bieżący kod błędu, można pobrać z funkcją składową GetLastError, jest WSAEWOULDBLOCK, wskazując, że wywołanie nie zostałoby zwrócone natychmiast z powodu trybu. (CSocket
nigdy nie zwraca WSAEWOULDBLOCK. Klasa zarządza blokowaniem.
Zachowanie gniazd różni się w 32-bitowych i 64-bitowych systemach operacyjnych (takich jak Windows 95 lub Windows 98) niż w 16-bitowych systemach operacyjnych (takich jak Windows 3.1). W przeciwieństwie do 16-bitowych systemów operacyjnych, 32-bitowe i 64-bitowe systemy operacyjne korzystają z wielozadaniowości i zapewniają wielowątkowy sposób. W 32-bitowych i 64-bitowych systemach operacyjnych można umieścić gniazda w osobnych wątkach roboczych. Gniazdo w wątku może blokować bez zakłócania innych działań w aplikacji i bez poświęcania czasu obliczeniowego na blokowanie. Aby uzyskać informacje na temat programowania wielowątkowego, zobacz artykuł wielowątkowość.
Uwaga
W aplikacjach wielowątkowych można użyć blokowania, CSocket
aby uprościć projekt programu bez wpływu na czas odpowiedzi interfejsu użytkownika. Dzięki obsłudze interakcji użytkownika w głównym wątku i CSocket
przetwarzaniu w alternatywnych wątkach można oddzielić te operacje logiczne. W aplikacji, która nie jest wielowątkowa, te dwa działania muszą być łączone i obsługiwane jako pojedynczy wątek, co zwykle oznacza użycie CAsyncSocket
, aby można było obsługiwać żądania komunikacji na żądanie lub zastąpić CSocket::OnMessagePending
do obsługi akcji użytkownika podczas długotrwałego działania synchronicznego.
Pozostała część tej dyskusji dotyczy programistów przeznaczonych dla 16-bitowych systemów operacyjnych:
Zwykle, jeśli używasz CAsyncSocket
metody , należy unikać używania operacji blokujących i zamiast tego działać asynchronicznie. W operacjach asynchronicznych od momentu, w którym otrzymasz kod błędu WSAEWOULDBLOCK po wywołaniu Receive
metody , na przykład czekasz, aż OnReceive
funkcja składowa zostanie wywołana, aby powiadomić Cię o ponownym odczytaniu. Wywołania asynchroniczne są wykonywane przez wywołanie odpowiedniej funkcji powiadamiania wywołania zwrotnego gniazda, takiej jak OnReceive.
W systemie Windows wywołania blokujące są uznawane za złe rozwiązanie. Domyślnie CAsyncSocket obsługuje wywołania asynchroniczne i musisz zarządzać blokowaniem przy użyciu powiadomień zwrotnych. Z drugiej strony klasa CSocket jest synchroniczna. Pompuje komunikaty systemu Windows i zarządza blokowaniem.
Aby uzyskać więcej informacji na temat blokowania, zobacz specyfikację gniazd systemu Windows. Aby uzyskać więcej informacji na temat funkcji "Wł.", zobacz Windows Sockets: Sockets and Windows Sockets: Deriving from Socket Classes (Gniazda systemu Windows: wyprowadzanie z klas gniazd).
Aby uzyskać więcej informacji, zobacz: