Created
March 19, 2026 19:15
-
-
Save m1irka/a81d8befe872ee2e3bdb41553369b80e to your computer and use it in GitHub Desktop.
чат на TCP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <ws2tcpip.h> | |
| #include <windows.h> | |
| #include <iostream> | |
| #include <string> | |
| using namespace std; | |
| #pragma comment (lib, "Ws2_32.lib") | |
| #define DEFAULT_BUFLEN 4096 | |
| #define SERVER_IP "127.0.0.1" | |
| #define DEFAULT_PORT "8888" | |
| SOCKET client_socket; | |
| string nick; | |
| DWORD WINAPI Sender(void* param) { | |
| while (true) { | |
| char query[DEFAULT_BUFLEN]; | |
| cin.getline(query, DEFAULT_BUFLEN); | |
| string message = nick + ": " + query; | |
| send(client_socket, message.c_str(), message.size(), 0); | |
| } | |
| } | |
| DWORD WINAPI Receiver(void* param) { | |
| while (true) { | |
| char response[DEFAULT_BUFLEN]; | |
| int result = recv(client_socket, response, DEFAULT_BUFLEN, 0); | |
| if (result <= 0) continue; | |
| response[result] = '\0'; | |
| cout << response << "\n"; | |
| } | |
| } | |
| BOOL ExitHandler(DWORD whatHappening) { | |
| switch (whatHappening) { | |
| case CTRL_C_EVENT: | |
| case CTRL_BREAK_EVENT: | |
| case CTRL_CLOSE_EVENT: | |
| case CTRL_LOGOFF_EVENT: | |
| case CTRL_SHUTDOWN_EVENT: | |
| cout << "Shutting down...\n"; | |
| Sleep(1000); | |
| send(client_socket, "off", 3, 0); | |
| return TRUE; | |
| default: | |
| return FALSE; | |
| } | |
| } | |
| int main() { | |
| cout << "Enter your nickname: "; | |
| getline(cin, nick); | |
| SetConsoleCtrlHandler((PHANDLER_ROUTINE)ExitHandler, true); | |
| system("title Client"); | |
| WSADATA wsaData; | |
| int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); | |
| if (iResult != 0) { | |
| cout << "WSAStartup failed with error: " << iResult << "\n"; | |
| return 1; | |
| } | |
| addrinfo hints{}; | |
| hints.ai_family = AF_UNSPEC; | |
| hints.ai_socktype = SOCK_STREAM; | |
| hints.ai_protocol = IPPROTO_TCP; | |
| addrinfo* result = nullptr; | |
| iResult = getaddrinfo(SERVER_IP, DEFAULT_PORT, &hints, &result); | |
| if (iResult != 0) { | |
| cout << "getaddrinfo failed with error: " << iResult << "\n"; | |
| WSACleanup(); | |
| return 2; | |
| } | |
| addrinfo* ptr = nullptr; | |
| for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { | |
| client_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); | |
| if (client_socket == INVALID_SOCKET) { | |
| cout << "Socket creation failed with error: " << WSAGetLastError() << "\n"; | |
| WSACleanup(); | |
| return 3; | |
| } | |
| iResult = connect(client_socket, ptr->ai_addr, (int)ptr->ai_addrlen); | |
| if (iResult == SOCKET_ERROR) { | |
| closesocket(client_socket); | |
| client_socket = INVALID_SOCKET; | |
| continue; | |
| } | |
| break; | |
| } | |
| freeaddrinfo(result); | |
| if (client_socket == INVALID_SOCKET) { | |
| cout << "Unable to connect to server!\n"; | |
| WSACleanup(); | |
| return 5; | |
| } | |
| CreateThread(0, 0, Sender, 0, 0, 0); | |
| CreateThread(0, 0, Receiver, 0, 0, 0); | |
| Sleep(INFINITE); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <winsock2.h> | |
| #include <iostream> | |
| #include <vector> | |
| using namespace std; | |
| #define MAX_CLIENTS 20 | |
| #define DEFAULT_BUFLEN 4096 | |
| #pragma comment(lib, "ws2_32.lib") | |
| #pragma warning(disable:4996) | |
| SOCKET server_socket; | |
| vector<string> history; | |
| int main() { | |
| setlocale(0, ""); | |
| system("title Server"); | |
| cout << "Starting server... done.\n"; | |
| WSADATA wsa; | |
| if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { | |
| cout << "Failed. Error code: " << WSAGetLastError() << "\n"; | |
| return 1; | |
| } | |
| if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { | |
| cout << "Failed to create socket: " << WSAGetLastError() << "\n"; | |
| return 2; | |
| } | |
| cout << "Server socket created... done.\n"; | |
| sockaddr_in server{}; | |
| server.sin_family = AF_INET; | |
| server.sin_addr.s_addr = INADDR_ANY; | |
| server.sin_port = htons(8888); | |
| if (bind(server_socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { | |
| cout << "Bind failed with error code: " << WSAGetLastError() << "\n"; | |
| return 3; | |
| } | |
| cout << "Socket bind... done.\n"; | |
| listen(server_socket, MAX_CLIENTS); | |
| cout << "Server is waiting for incoming connections...\nPlease start one or more client applications.\n"; | |
| fd_set readfds; | |
| SOCKET client_socket[MAX_CLIENTS]{}; | |
| while (true) { | |
| FD_ZERO(&readfds); | |
| FD_SET(server_socket, &readfds); | |
| for (int i = 0; i < MAX_CLIENTS; i++) { | |
| SOCKET s = client_socket[i]; | |
| if (s > 0) FD_SET(s, &readfds); | |
| } | |
| if (select(0, &readfds, NULL, NULL, NULL) == SOCKET_ERROR) { | |
| cout << "Select function failed with error code: " << WSAGetLastError() << "\n"; | |
| return 4; | |
| } | |
| SOCKET new_socket; | |
| sockaddr_in address; | |
| int addrlen = sizeof(sockaddr_in); | |
| if (FD_ISSET(server_socket, &readfds)) { | |
| if ((new_socket = accept(server_socket, (sockaddr*)&address, &addrlen)) < 0) { | |
| perror("Accept function error"); | |
| return 5; | |
| } | |
| for (int i = 0; i < history.size(); i++) { | |
| send(new_socket, history[i].c_str(), history[i].size(), 0); | |
| } | |
| cout << "New connection, socket fd: " << new_socket | |
| << ", IP: " << inet_ntoa(address.sin_addr) | |
| << ", Port: " << ntohs(address.sin_port) << "\n"; | |
| for (int i = 0; i < MAX_CLIENTS; i++) { | |
| if (client_socket[i] == 0) { | |
| client_socket[i] = new_socket; | |
| cout << "Added to socket list at index " << i << "\n"; | |
| break; | |
| } | |
| } | |
| } | |
| for (int i = 0; i < MAX_CLIENTS; i++) { | |
| SOCKET s = client_socket[i]; | |
| if (FD_ISSET(s, &readfds)) { | |
| getpeername(s, (sockaddr*)&address, (int*)&addrlen); | |
| char client_message[DEFAULT_BUFLEN]; | |
| int client_message_length = recv(s, client_message, DEFAULT_BUFLEN, 0); | |
| if (client_message_length <= 0) { | |
| cout << "Client #" << i << " disconnected\n"; | |
| client_socket[i] = 0; | |
| continue; | |
| } | |
| client_message[client_message_length] = '\0'; | |
| string check_exit = client_message; | |
| if (check_exit == "off") { | |
| cout << "Client #" << i << " disconnected\n"; | |
| client_socket[i] = 0; | |
| } | |
| else { | |
| string temp = client_message; | |
| temp += "\n"; | |
| history.push_back(temp); | |
| for (int j = 0; j < MAX_CLIENTS; j++) | |
| if (client_socket[j] != 0 && client_socket[j] != s) | |
| send(client_socket[j], client_message, client_message_length, 0); | |
| } | |
| } | |
| } | |
| } | |
| WSACleanup(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment