Udostępnij przez


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 oraz Windows Sockets: Converting Strings (Gniazda systemu Windows: konwertowanie ciągów znakó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 nieblokującym". Funkcje gniazd w trybie blokującym (lub synchronicznym) nie zwracają, dopóki nie zakończą operacji. 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ąć nieokreślony czas, ponieważ oczekuje na wysłanie przez aplikację wysyłającą, co dzieje się tak wtedy, gdy używasz CSocket lub używając CAsyncSocket z blokowaniem. Jeśli obiekt jest w trybie nieblokującym (działa asynchronicznie), wywołanie zwraca natychmiast, a bieżący kod błędu, który można pobrać za pomocą funkcji składowej CAsyncSocket, to WSAEWOULDBLOCK, co wskazuje, że wywołanie zostałoby zablokowane, gdyby nie zostało zwrócone natychmiast z powodu trybu. (CSocket nigdy nie zwraca WSAEWOULDBLOCK. Klasa zarządza blokowaniem za Ciebie.)

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 z wywłaszczeniem i zapewniają wielowątkowość. 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 / Notatka

W aplikacjach wielowątkowych można wykorzystać blokującą naturę CSocket do uproszczenia projektu swojego programu bez wpływu na responsywność 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, którzy celują w 16-bitowe systemy operacyjne.

Zwykle, jeśli używasz CAsyncSocket, należy unikać używania operacji blokujących i zamiast tego pracować asynchronicznie. W operacjach asynchronicznych od momentu, gdy otrzymasz kod błędu WSAEWOULDBLOCK po wywołaniu Receive metody, na przykład czekasz, aż funkcja członkowska OnReceive zostanie wywołana, aby powiadomić Cię, że możesz ponownie odczytać. Wywołania asynchroniczne są realizowane poprzez wywołanie odpowiedniej funkcji powiadamiania zwrotnego gniazda, takiej jak OnReceive.

W systemie Windows wywołania blokujące są uznawane za złą praktykę. Domyślnie CAsyncSocket obsługuje wywołania asynchroniczne, a zarządzanie blokowaniem musisz przeprowadzać samodzielnie, korzystając z 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 "On", zobacz Windows Sockets: Powiadomienia Gniazd i Windows Sockets: Wyprowadzanie z Klas Gniazd.

Aby uzyskać więcej informacji, zobacz:

Zobacz także

Windows Sockets w MFC
CAsyncSocket::OnSend