Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active February 6, 2025 08:16
Show Gist options
  • Save sunmeat/068b8df3d7da02e6548ed53491989443 to your computer and use it in GitHub Desktop.
Save sunmeat/068b8df3d7da02e6548ed53491989443 to your computer and use it in GitHub Desktop.
TCP + threads: CLIENT SIDE
// !!! SERVER SIDE: https://git.io/JslUY
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <windows.h>
#include <ws2tcpip.h>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define PAUSE 1
// спроба підключитися до адреси, поки не вдасться
SOCKET ConnectSocket = INVALID_SOCKET;
DWORD WINAPI Sender(void* param)
{
while (true)
{
// відправити початковий буфер
char* message = new char[200];
cout << "Будь ласка, введіть повідомлення для сервера: ";
cin.getline(message, 199);
int iResult = send(ConnectSocket, message, (int)strlen(message), 0);
if (iResult == SOCKET_ERROR) {
cout << "помилка відправлення: " << WSAGetLastError() << "\n";
closesocket(ConnectSocket);
WSACleanup();
return 15;
}
else {
cout << "дані успішно надіслані на сервер: " << message << "\n";
// cout << "байтів з клієнта надіслано: " << iResult << "\n";
delete[] message;
Sleep(PAUSE);
}
}
return 0;
}
DWORD WINAPI Receiver(void* param)
{
while (true)
{
// приймати дані, поки співрозмовник не закриє з'єднання
char answer[DEFAULT_BUFLEN];
int iResult = recv(ConnectSocket, answer, DEFAULT_BUFLEN, 0);
answer[iResult] = '\0';
if (iResult > 0) {
cout << "\nпроцес сервера надіслав повідомлення: " << answer << "\n";
// cout << "байтів отримано: " << iResult << "\n";
}
else if (iResult == 0)
cout << "з'єднання з сервером закрито.\n";
else
cout << "помилка прийому: " << WSAGetLastError() << "\n";
}
return 0;
}
int main()
{
SetConsoleOutputCP(1251);
system("title CLIENT SIDE");
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// ініціалізація Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
cout << "не вдалося ініціалізувати Winsock: " << iResult << "\n";
return 11;
}
else {
// cout << "підключення Winsock.dll пройшло успішно!\n";
Sleep(PAUSE);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// отримання адреси і порту сервера
const char* ip = "localhost"; // за замовчуванням, обидва додатки, і клієнт, і сервер, працюють на одній машині
// cout << "Будь ласка, введіть ім'я сервера: ";
// cin.getline(ip, 199);
// iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); // розкоментувати, якщо потрібно отримати ім'я сервера з командного рядка
addrinfo* result = NULL;
iResult = getaddrinfo(ip, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
cout << "getaddrinfo не вдалося: " << iResult << "\n";
WSACleanup();
return 12;
}
else {
// cout << "отримання адреси і порту клієнта пройшло успішно!\n";
Sleep(PAUSE);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
for (addrinfo* ptr = result; ptr != NULL; ptr = ptr->ai_next) { // серверів може бути кілька, тому не завадить цикл
// створення SOCKET для підключення до сервера
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
cout << "не вдалося створити socket: " << WSAGetLastError() << "\n";
WSACleanup();
return 13;
}
// підключення до сервера
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
// cout << "створення socket на клієнті пройшло успішно!\n";
Sleep(PAUSE);
break;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
cout << "неможливо підключитися до сервера!\n";
WSACleanup();
return 14;
}
else {
// cout << "підключення до сервера пройшло успішно!\n";
Sleep(PAUSE);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CreateThread(0, 0, Sender, 0, 0, 0);
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// закрити з'єднання, оскільки більше даних не буде надіслано
// iResult = shutdown(ConnectSocket, SD_SEND);
// if (iResult == SOCKET_ERROR) {
// cout << "не вдалося закрити з'єднання: " << WSAGetLastError() << "\n";
// closesocket(ConnectSocket);
// WSACleanup();
// return 16;
// }
// else {
// cout << "клієнт ініціює закриття з'єднання з сервером.\n";
// }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CreateThread(0, 0, Receiver, 0, 0, 0);
// очищення
//closesocket(ConnectSocket);
//WSACleanup();
//cout << "клієнт завершує свою роботу!\n";
//return 0;
Sleep(INFINITE);
}
@sunmeat
Copy link
Author

sunmeat commented Feb 6, 2025

SERVER SIDE: https://git.io/JslUY

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment