Winsock. Sieci Komputerowe II Wyk ład 3

Podobne dokumenty
Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project

TCP - receive buffer (queue), send buffer (queue)

Aplikacja Sieciowa wątki po stronie klienta

Oprogramowanie komunikacyjne dla Internetu rzeczy Laboratorium nr 4 komunikacja unicastowa IPv6

Programowanie TCP/IP

Programowanie Sieciowe 1

Iteracyjny serwer TCP i aplikacja UDP

ZESZYTY ETI ZESPOŁU SZKÓŁ W TARNOBRZEGU Nr 1 Seria: Teleinformatyka 2013

Architektury systemów rozproszonych LABORATORIUM. Ćwiczenie 1

Architektura typu klient serwer: uproszczony klient POP3

Podstawowe typy serwerów

socket(int domain, int type, int protocol)

Programowanie przy użyciu gniazdek

Klient-Serwer Komunikacja przy pomocy gniazd

Instytut Teleinformatyki

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Interfejs programowy Windows Sockets 2. Aplikacja klient-serwer TCP Echo

3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);

Gniazda UDP. Bartłomiej Świercz. Łódź, 3 kwietnia Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda UDP

MeetingHelper. Aplikacja Android ułatwiająca przekazywanie materiałów pomiędzy uczestnikami spotkania. Instrukcja obsługi dla programisty

Sockety TCP/IP - podstawy. Sieci Komputerowe II Wyk ład 2

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

Krótkie wprowadzenie do korzystania z OpenSSL

Gniazda BSD implementacja w C#

Gniazda surowe. Bartłomiej Świercz. Łódź,9maja2006. Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda surowe

Transport. część 2: protokół TCP. Sieci komputerowe. Wykład 6. Marcin Bieńkowski

Programowanie sieciowe

Dokumentacja techniczna

Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA. Marcin Lewandowski [ mlew@ippt.gov.pl ]

Gniazda. S. Samolej: Gniazda 1

Komunikator internetowy w C#

Tworzenie aplikacji rozproszonej w Sun RPC

Ćwiczenia 2 IBM DB2 Data Studio

Transport. część 2: protokół TCP. Sieci komputerowe. Wykład 6. Marcin Bieńkowski

Protokół ARP. dr Zbigniew Lipiński. Instytut Matematyki i Informatyki ul. Oleska Opole zlipinski@math.uni.opole.pl

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Literatura uzupełniająca: W. Richard Stevens, Programowanie zastosowań sieciowych w systemie Unix WNT 1998

Od uczestników szkolenia wymagana jest umiejętność programowania w języku C oraz podstawowa znajomość obsługi systemu Windows.

Architektura typu klient serwer: przesyłanie pliku tekstowo oraz logowania do serwera za pomocą szyfrowanego hasła

Mechanizmy pracy równoległej. Jarosław Kuchta

Komunikacja przez sieć z wykorzystaniem biblioteki WINSOCK. dr inż. Piotr Kaczmarek Instytut Automatyki i Inżynierii Informatycznej

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Politechnika Łódzka. Instytut Systemów Inżynierii Elektrycznej. Laboratorium przyrządów wirtualnych. Ćwiczenie 4

FTP File Transfer Protocol

Schemat dla UDP. = możliwe zablokowanie aplikacji KLIENT SERWER. s=socket(...) bind(s,...) recvfrom(s,...) sendto(s,...) recvfrom(s,...

PHP może zostać rozszerzony o mechanizmy dostępu do różnych baz danych:

RPC. Zdalne wywoływanie procedur (ang. Remote Procedure Calls )

Sieci komputerowe. Zajęcia 3 c.d. Warstwa transportu, protokoły UDP, ICMP

Laboratorium 3.4.2: Zarządzanie serwerem WWW

Gniazda BSD. Procesy w środowisku sieciowym. Gniazda podstawowe funkcje dla serwera. Gniazda podstawowe funkcje dla klienta

Tryb bezpołączeniowy (datagramowy)

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Dzisiejszy wykład. Wzorce projektowe. Visitor Client-Server Factory Singleton

Instrukcja instalacji Control Expert 3.0

Dokumentacja smsapi wersja 1.4

Dokumentacja końcowa projektu z ZPR

Tomasz Greszata - Koszalin

Serwer współbieżny połączeniowy

Zadanie 2: transakcyjny protokół SKJ (2015)

Specyfikacja API Runtime BAS 3.0

Zadanie1: Odszukaj w serwisie internetowym Wikipedii informacje na temat protokołu http.

Politechnika Łódzka. Instytut Systemów Inżynierii Elektrycznej

1. Tworzenie nowego projektu.

Internet Control Message Protocol Aplikacja ping

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Przykłady interfejsu TCP i UDP w Javie

Dokumentacja techniczna API systemu SimPay.pl

Proxy (pełnomocnik) Cel: Zastosowanie: Dostarczyć zamiennik pewnego obiektu, pozwalający kontrolować dostęp do niego.

Co to jest NODE.JS? Nowoczesne środowisko programistyczne

Wybrane działy Informatyki Stosowanej

Projektowanie oprogramowania systemów KOMUNIKACJA SIECIOWA I SYSTEMY RPC

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Informacje które należy zebrać przed rozpoczęciem instalacji RelayFax.

Qt in Education. Sieć I drukowanie

Informatyka I. Standard JDBC Programowanie aplikacji bazodanowych w języku Java

Programowanie rozproszone w języku Java

Kolejkowanie wiadomości Standard MQ (JMS)

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Instalacja NOD32 Remote Administrator

Gniazda BSD. komunikacja bezpołączeniowa

Specyfikacja instalacji usługi SMS Premium w Przelewy24.pl

Technologie sieciowe Sprawozdanie z labolatorium. Lista 5

Wskaźniki w C. Anna Gogolińska

Moduł Ethernetowy. instrukcja obsługi. Spis treści

Sieci komputerowe. Wykład 5: Warstwa transportowa: TCP i UDP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Instrukcja instalacji aplikacji i konfiguracji wersji sieciowej. KomKOD

NS-2. Krzysztof Rusek. 26 kwietnia 2010

Specyfikacja techniczna. mprofi Interfejs API

część 8 wskaźniki - podstawy Jarosław Gramacki Instytut Informatyki i Elektroniki Podstawowe pojęcia

Tablice, funkcje - wprowadzenie

Statystyka protokołów i połączeń sieciowych.

Zdalne wywoływanie procedur RPC

Zdalne wywoływanie procedur RPC

INSTRUKCJA KONFIGURACJI KLIENTA POCZTOWEGO

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Instrukcja instalacji oprogramowania dla środowiska Windows

Biblioteka standardowa - operacje wejścia/wyjścia

Transkrypt:

Winsock Sieci Komputerowe II Wyk ład 3

Plan Przygotowanie środowiska Inicjacja Winsock Aplikacja klienta: tworzenie socketu łączenie z socketem serwera wysyłanie i odbieranie danych rozłączanie klienta Aplikacja serwera: tworzenie socketu wiązanie socketu nasłuchiwanie akceptowanie połączenia odbieranie i wysyłanie danych rozłączanie serwera

Przygotowanie środowiska Wszelkie prezentowane uwagi dotyczą środowiska MS Visual Studio W środowisku należy ustawić dostęp do biblioteki WS2_32.lib Na początku programu należy dołączyć dwa pliki nagłówkowe: winsock2.h zawierający większość funkcji, struktur i definicji do obsługi socketów ws2tcpip.h zawierający pozostałe funkcje i struktury nie ujęte w winsock2.h a zawarte w dokumencie WinSock 2 Protocol-Specific Annex dla protokołu TCP/IP Czasami może być konieczne użycie plików nagłówkowych iphlpapi.h (IP Helper API) i/lub windows.h o warunkach użycia tych plików należy doczytać w dokumentacji środowiska

Windows Inicjacja Winsock Przed przystąpieniem do korzystania z funkcji biblioteki Winsock należy zainicjować bibliotekę dynamiczną Windows Sockets DLL (WS2_32.dll) w następujący sposób: stworzyć obiekt typu WSADATA o nazwie wsadata WSADATA wsadata; wywołać funkcję WSAStartup i sprawdzić wynik wywołania pod względem błędów int iresult; // Initialize Winsock iresult = WSAStartup(MAKEWORD(2,2), &wsadata); if (iresult!= 0) { printf("wsastartup failed: %d\n", iresult); return 1; }

Tworzenie socketu dla klienta krok 1 Zadeklarować obiekt addrinfo zawierający strukturę sockaddr i zainicjować te wartości struct addrinfo *result = NULL, *ptr = NULL, hints; ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; Nie jest określona wersja adresów IP zarówno adres IPv4, jak i IPv6 mogą być użyte (ai_family) Wymaganym przez aplikację typem socketu jest socket strumieniowy dla protokołu TCP (ai_socktype, ai_protocol)

Tworzenie socketu dla klienta krok 2 Wywołać funkcję getaddrinfo żądanie adresu IP dla nazwy serwera podanej w linii komend #define DEFAULT_PORT "27015" // Resolve the server address and port iresult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); if (iresult!= 0) { printf("getaddrinfo failed: %d\n", iresult); WSACleanup(); return 1; } Port TCP po stronie serwera, z jakim w tym przykładzie chce się połączyć klient, to port 27015 (stała DEFAULT_PORT) Funkcja getaddrinfo zwraca wartość, która jest sprawdzana pod kątem wystąpienia błędów. WSACleanup kończy użycie WS2_32.dll

Tworzenie socketu dla klienta krok 3 Utworzyć obiekt ConnectSocket typu SOCKET SOCKET ConnectSocket = INVALID_SOCKET;

Tworzenie socketu dla klienta krok 4 Wywołać funkcję socket i przypisać zwracaną przez nią wartość do zmiennej ConnectSocket // Attempt to connect to the first address returned by the call to getaddrinfo ptr=result; // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); Używany jest pierwszy adres IP zwrócony przez funkcję getaddrinfo, który odpowiada parametrom określonym w strukturze hints (typ socketu SOCK_STREAM, typ protokołu IPROTO_TCP, nieokreślona wersja adresów IP AF_UNSPEC) Jeśli klient ma się kontaktować z serwerem wyłącznie za pośrednictwem adresu IP w wersji 4 lub IP w wersji 6 to zamiast AF_UNSPEC należy użyć odpowiednio AF_INET lub AF_INET6

Łączenie z socketem serwera (1) Sprawdzenie czy nie wystąpiły błędy podczas tworzenia socketu // Connect to server. iresult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iresult == SOCKET_ERROR) { closesocket(connectsocket); ConnectSocket = INVALID_SOCKET; } Użyta wcześniej funkcja getaddrinfo jest używana do określenia wartości w strukturze sockaddr() W przykładzie pierwszy adres IP zwrócony przez getaddrinfo służy do określenia zawartości struktury sockaddr, która następnie jest przekazywana do funkcji socket Informacje zawarte w strukturze sockaddr zawierają: adres IP serwera, z którym klient chce się połączyć numer portu serwera, z którym klient chce się połączyć (w tym przypadku port 27015 określony przy wywoływaniu funkcji getaddrinfo)

Łączenie z socketem serwera (2) Sprawdzenie czy nie wystąpiły błędy podczas tworzenia socketu // Should really try the next address returned by getaddrinfo if the connect call failed // But for this simple example we just free the resources // returned by getaddrinfo and print an error message freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { printf("unable to connect to server!\n"); WSACleanup(); return 1; } Jeśli funkcja connect nie wykona się poprawnie dla pierwszego z adresów zwróconych przez getaddrinfo, wtedy należy skorzystać z następnej struktury addrinfo z listy zwróconej przez getaddrinfo W tym przykładzie inne podejście po prostu zwolnienie zasobów i zakończenie programu komunikatem o błędzie

Wysyłanie i odbieranie danych (1) Po nawiązaniu połączenia z socketem serwera klient wysyła i odbiera dane za pomocą funkcji send i recv obydwie funkcje zwracają liczbę wysłanych (odebranych) bajtów lub kod błędu obydwie funkcje również korzystają z tych samych parametrów: aktywny socket, bufor znaków, liczba bajtów do wysłania lub odebrania, odpowiednie znaczniki #define DEFAULT_BUFLEN 512 int recvbuflen = DEFAULT_BUFLEN; char *sendbuf = "this is a test"; char recvbuf[default_buflen]; int iresult;

Wysyłanie i odbieranie danych (2) // Send an initial buffer iresult = send(connectsocket, sendbuf, (int) strlen(sendbuf), 0); if (iresult == SOCKET_ERROR) { printf("send failed: %d\n", WSAGetLastError()); closesocket(connectsocket); WSACleanup(); return 1; } printf("bytes Sent: %ld\n", iresult);

Wysyłanie i odbieranie danych (3) // shutdown the connection for sending since no more data will be sent // the client can still use the ConnectSocket for receiving data iresult = shutdown(connectsocket, SD_SEND); if (iresult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(connectsocket); WSACleanup(); return 1; }

Wysyłanie i odbieranie danych (4) // Receive data until the server closes the connection do { iresult = recv(connectsocket, recvbuf, recvbuflen, 0); if (iresult > 0) printf("bytes received: %d\n", iresult); else if (iresult == 0) printf("connection closed\n"); else printf("recv failed: %d\n", WSAGetLastError()); } while (iresult > 0);

Rozłączanie klienta krok 1 Gdy klient zakończy wysyłanie danych, rozłącza się z serwerem // shutdown the send half of the connection since no more data will be sent iresult = shutdown(connectsocket, SD_SEND); if (iresult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(connectsocket); WSACleanup(); return 1; } Funkcja shutdown z parametrem SD_SEND stosowana do zamknięcia strony wysyłającej Umożliwia to serwerowi zwolnienie wykorzystywanych w komunikacji zasobów, a klient może nadal otrzymywać dane przez ten socket

Rozłączanie klienta krok 2 Gdy klient zakończy odbieranie danych zamyka socket // cleanup closesocket(connectsocket); WSACleanup(); return 0; Funkcja closesocket stosowana do zamknięcia socketu Po zakończeniu korzystania przez aplikację klienta z biblioteki WS2_32.dll wywoływana jest funkcja WSACleanup zamykająca bibliotekę i zwalniająca używane zasoby.

Tworzenie socketu dla serwera krok 1 Zadeklarować obiekt addrinfo zawierający strukturę sockaddr #define DEFAULT_PORT "27015" struct addrinfo *result = NULL, *ptr = NULL, hints; ZeroMemory(&hints, sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; AF_INET adres IPv4 STOCK_STREAM socket strumieniowy IPPROTO_TCP protokół TCP AI_PASSIVE znacznik oznaczający, że ma być użyta struktura adresu socketu zwrócona przez funkcję bind (parametr INADDR_ANY lub IN6ADDR_ANY_INIT) 27015 numer portu, do którego powinien się łączyć klient

Tworzenie socketu dla serwera krok 2 Wywołać funkcję getaddrinfo przy użyciu struktury addrinfo // Resolve the local address and port to be used by the server iresult = getaddrinfo(null, DEFAULT_PORT, &hints, &result); if (iresult!= 0) { printf("getaddrinfo failed: %d\n", iresult); WSACleanup(); return 1; } Funkcja getaddrinfo zwraca wartość, która jest sprawdzana pod kątem wystąpienia błędów. WSACleanup kończy użycie WS2_32.dll

Tworzenie socketu dla serwera krok 3 Utworzyć obiekt ListenSocket typu SOCKET SOCKET ListenSocket = INVALID_SOCKET;

Tworzenie socketu dla klienta krok 4 Wywołać funkcję socket i przypisać zwracaną przez nią wartość do zmiennej ListenSocket // Create a SOCKET for the server to listen for client connections ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); Używany jest pierwszy adres IP zwrócony przez funkcję getaddrinfo, który odpowiada parametrom określonym w strukturze hints (typ socketu SOCK_STREAM, typ protokołu IPROTO_TCP, adres IPv4 AF_INET) Jeśli klient ma się kontaktować z serwerem wyłącznie za pośrednictwem adresu IP w wersji to zamiast AF_INET należy użyć AF_INET6, te dwa typy socketów muszą być osobno obsługiwane przez aplikację. Od wersji Vista istnieje możliwość stworzenia pojedynczego socketu IPv6, który może pracować w trybie dual-stack i nasłuchiwać jednocześnie na dwóch wersjach adresu IPv4 i IPv6

Tworzenie socketu dla klienta krok 5 Sprawdzenie, czy podczas tworzenia socketu nie wystąpiły błędy if (ListenSocket == INVALID_SOCKET) { printf("error at socket(): %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } Jeśli wystąpił błąd to wyświetlany jest odpowiedni komunikat Zasoby są zwracane WSACleanup kończy użycie WS2_32.dll

Wiązanie z socketem Aby serwer mógł akceptować połączenia od klienta, to musi być związany z adresem sieciowycm // Setup the TCP listening socket iresult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iresult == SOCKET_ERROR) { printf("bind failed: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(listensocket); WSACleanup(); return 1; } Struktura sockaddr przechowuje informacje o adresie IP, jego typie i numerze portu Funkcja bind uruchamiana jest dla utworzonego socketu (parametry socket i sockaddr) W przypadku wystąpienia błędu, jego obsługa polega na wygenerowaniu napisu informującego o błędzie, zwróceniu zasobów i zakończeniu użycia WS2_32.dll

Nasłuchiwanie na sockecie Po związaniu socketu z adresem IP i portem, serwer przechodzi w stan nasłuchiwania (oczekiwania na połączenia z klientem) if ( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR ) { printf( "Error at bind(): %ld\n", WSAGetLastError() ); closesocket(listensocket); WSACleanup(); return 1; } Funkcja listen wywoływana jest z dwoma parametrami utworzonym socketem i wartością określającą maksymalną długość kolejki połączeń oczekujących na zaakceptowanie (w tym przykładzie stała SOMAXCONN) Stała SOMAXCONN oznacza maksymalną rozsądnie możliwą liczbę oczekujących połączeń W przypadku wystąpienia błędu, jego obsługa polega na wygenerowaniu napisu zamknięciu socketu i zakończeniu użycia WS2_32.dll

Akceptowanie połączeń krok 1 Gdy socket jest w trybie nasłuchiwania, program musi obsługiwać żądania połączenia przychodzące na ten socket SOCKET ClientSocket; Utworzenie temporalnego obiektu typu SOCKET, służącego do obsługi połączeń przychodzących.

Akceptowanie połączeń krok 2 Akceptowanie połączenia ClientSocket = INVALID_SOCKET; // Accept a client socket ClientSocket = accept(listensocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed: %d\n", WSAGetLastError()); closesocket(listensocket); WSACleanup(); return 1; } Zazwyczaj aplikacja serwera nasłuchuje cały czas, aby przyjmować kolejne połączenia od klientów (kolejne połączenia są obsługiwane przez odrębne wątki) Po wystąpieniu próby nawiązania połączenia, aplikacja serwera akceptuje połączenie jedną z funkcji accept, AcceptEx lub WSAAccept i przekazuje sterowanie do innego wątku, który zajmuje się obsługą tego zgłoszenia W typ prostym przypadku serwer nasłuchuje i akceptuje wyłącznie jedno połączenie (nie ma obsługi wielu wątków)

Akceptowanie połączeń krok 3 Zaakceptowanie połączenia klienta przez serwer powinno spowodować przekazanie zaakceptowanego socketu klienta do wątku roboczego lub do odpowiedniego portu we/wy, a serwer powinien przejść do akceptowania kolejnych połączeń W tym prostym przykładzie serwer po zaakceptowaniu połączenia przechodzi do obsługi tego połączenia Istnieje wiele innych technik programistycznych, które mogą być użyte do nasłuchiwania i akceptowania połączeń przychodzących. Są to m.in. funkcje select lub WSAPoll. Przykłady znajdują się w MS Windows Software Development Kit (SDK)

Akceptowanie połączeń uwagi Główna różnica pomiędzy systemem Windows a systemami unixowymi w zastosowaniu socketów występuje w momencie zaakceptowania połączenia W systemach unixowych proces serwera wywołuje funkcję fork by utworzyć proces potomny do obsługi połączenia z klientem otrzymując od serwera socket Systemy windowsowe nie obsługują funkcji fork, używając w zamian techniki wielowątkowości

Odbieranie i wysyłanie danych (1) Po nawiązaniu połączenia z socketem klienta serwer odbiera i wysyła dane za pomocą funkcji recv i send obydwie funkcje zwracają liczbę wysłanych (odebranych) bajtów lub kod błędu obydwie funkcje również korzystają z tych samych parametrów: aktywny socket, bufor znaków, liczba bajtów do wysłania lub odebrania, odpowiednie znaczniki #define DEFAULT_BUFLEN 512 char recvbuf[default_buflen]; int iresult, isendresult; int recvbuflen = DEFAULT_BUFLEN; // Receive until the peer shuts down the connection do { } while (iresult > 0);

Odbieranie i wysyłanie danych (2) do { iresult = recv(clientsocket, recvbuf, recvbuflen, 0); if (iresult > 0) { printf("bytes received: %d\n", iresult); } // Echo the buffer back to the sender isendresult = send(clientsocket, recvbuf, iresult, 0); if (isendresult == SOCKET_ERROR) { printf("send failed: %d\n", WSAGetLastError()); closesocket(clientsocket); WSACleanup(); return 1; } printf("bytes sent: %d\n", isendresult);

Odbieranie i wysyłanie danych (3) else if (iresult == 0) printf("connection closing...\n"); else { printf("recv failed: %d\n", WSAGetLastError()); closesocket(clientsocket); WSACleanup(); return 1; } } while (iresult > 0);

Rozłączanie serwera krok 1 Gdy serwer zakończy odbieranie danych od klienta i wysyłanie informacji zwrotnych, rozłącza się z klientem // shutdown the send half of the connection since no more data will be sent iresult = shutdown(clientsocket, SD_SEND); if (iresult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(clientsocket); WSACleanup(); return 1; } Funkcja shutdown z parametrem SD_SEND stosowana do zamknięcia strony wysyłającej Umożliwia to klientowi zwolnienie wykorzystywanych w komunikacji zasobów, a serwer może nadal otrzymywać dane przez ten socket

Rozłączanie serwera krok 2 Gdy klient zakończy odbieranie danych zamykany jest związany z nim socket // cleanup closesocket(clientsocket); WSACleanup(); return 0; Funkcja closesocket stosowana do zamknięcia socketu Po zakończeniu korzystania przez aplikację z biblioteki WS2_32.dll wywoływana jest funkcja WSACleanup zamykająca bibliotekę i zwalniająca używane zasoby.

Przykłady zaawansowane Dostępne w Windows SDK W przypadku Windows 7 zainstalowane w następującym katalogu: C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\NetDs\winsock Pięć katalogów: accept simple WSAPoll overlap iocp

Przykłady zaawansowane accept pokazuje zastosowanie funkcji select do obsługi wielu połączeń lub funkcji WSAAsyncSelect do akceptacji asynchronicznej simple trzy podstawowe programy ilustrujące korzystanie z wielu wątków przez serwer simples prosty serwer TCP/UDP simples_ioctl serwer wyłacznie TCP korzystający z funkcji select do obsługi wielu klientów simplec klient TCP/UDP WSAPoll prosty program pokazujący użycie funkcji WSAPoll overlap przykładowy serwer korzystający z nadpisywania portu I/O do obsługi wielu połączeń w sposób asynchroniczny z poziomu aplikacji jednowątkowej(acceptex) iocp trzy programy korzystające z funkcji WSAAccept (iocpserver), funkcji AcceptX (iocpserverx) i wielowątkowy klient (iocpclient)