Лабораторна робота №7 Паралельне програмування, потоки Порядок виконання: 1. Узгодити з викладачом варіант завдання. 2. Ознайомитись з теоретичними відомостями та прикладом реалізації багатопоточного сервера. 3. Ознайомитись з документацією на кожну з функцій, що використовуються у прикладі. 4. Створити проект в середовищі VisualStudio, запустити сервер та за допомогою відладчика перевірити його роботу з клієнтською програмую, що була розроблена у попередній роботі. 5. Забезпечити можливість зупинки сервера при введенні в консоль тексту «exit». 6. Обмежити максимальну кількість підключень значенням, що вказане у таблиці з варіантами. При перевищенні цього значення – не створювати підключення. 7. Забезпечити вивод повідомлень у консолі сервера відповідно до варіанту завдання. Максимальна кількість підключень Варіанти завдань
Disconnected: №_підключення 61
Disconnected: №_порту 6 10 New connection: №_порту Disconnected: №_порту 7 5 Connected: №_підключення Disconnected: кількість_повідомлень 8 6 Total clients: кількість_підключень Disconnected: кількість_пересланих_байт 12 10 New connection: №_порту Disconnected: кількість_пересланих_байт 13 5 Connected: №_підключення Disconnected: №_підключення 14 6 Total clients: кількість_підключень Disconnected: №_підключення Disconnected: №_порту 18 10 New connection: №_порту Disconnected: №_порту 19 5 Connected: №_підключення Disconnected: кількість_повідомлень 20 6 Total clients: кількість_підключень 62
23 9 Total clients: кількість_підключень Приклад реалізації багатопоточного сервера #undef UNICODE #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include #include #define MAX_THREADS 32 // Need to link with Ws2_32.lib #pragma comment (lib, "Ws2_32.lib") // #pragma comment (lib, "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" void clientThrd(LPVOID lpParam) { int iResult; SOCKET clientSocket = (SOCKET)lpParam; int iSendResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; // Receive until the peer shuts down the connection 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 with error: %d\n", WSAGetLastError()); closesocket(clientSocket); return; } printf("Bytes sent: %d\n", iSendResult); } else if (iResult == 0) printf("Connection closing...\n"); else { printf("recv failed with error: %d\n", WSAGetLastError()); 63 closesocket(clientSocket); return; } } while (iResult > 0); // shutdown the connection since we're done iResult = shutdown(clientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(clientSocket); return; } // cleanup closesocket(clientSocket); return; } int __cdecl main(void) { WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; struct addrinfo* result = NULL; struct addrinfo hints; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } // Setup the TCP listening socket 64 iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } do { // Accept a client socket SOCKET ClientSocket = INVALID_SOCKET; ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } _beginthread(clientThrd, 0, (LPVOID)ClientSocket); } while (true); closesocket(ListenSocket); WSACleanup(); return 0; } |