Untitled

 avatar
unknown
c_cpp
2 years ago
9.8 kB
5
Indexable
#include<iostream>
#include<winsock2.h>
#pragma comment (lib, "ws2_32.lib")// - директив, позволяющий избавиться от предупреждений, выдаваемых на стандартные библиотеки
#include<windows.h>// - так как работа с windows
#include<WinSock2.h>// - заголовочный файл для работы с сокетами
#include<WS2tcpip.h>// - дополнительный заголовок, так как работа с tcp/ip протоколами

#define WIN32_LEAN_AND_MEAN //- макрос, необходимый в случае с сетевыми вещами

using namespace std;

int main(){
	WSADATA wsaData;
	ADDRINFO hints; //- hints(подсказки)
	ADDRINFO* addrResult = NULL; // - указатель на addrinfo
	SOCKET ConnectSocket = INVALID_SOCKET; // - переменная типа socket(инициализируем invalid, так как сейчас он еще не создан, а значит неверный) 

	const char* sendBuffer = "Hello from client!"; // - строковой буфер
    char recvBuffer[512]; // - буфер для приема

	int result; // - переменная, отвечающая за различные коды возврата
	
	result = WSAStartup(MAKEWORD(2, 2), &wsaData);  // MAKEWORD - макрос
		                                            //WSAStartup - функция для загрузки бибилиотек
	if (result != 0) // так как функция WSASrartup возвращает 0
	{
		cout << "WSAStartup failed, result = " << result << endl;
		return 1; // если main возвращает не 0, значит что программа отработала с ошибкой, 1 - код ошибки
   }
	ZeroMemory(&hints, sizeof(hints)); // ZeroMemory - заполняет блок памяти нулями
	                                   //&hints - указатель на память
	                                   //sizeof - оператор, позволяющий определить длину зануляемой памяти
	hints.ai_family = AF_INET;       // - то, какие протоколы будут использоваться
	hints.ai_socktype = SOCK_STREAM; // - тип сокета(в данном случае потоковый сокет)
	hints.ai_protocol = IPPROTO_TCP; // - используемый протокол



	result = getaddrinfo("localhost", "666", &hints, &addrResult); // - проверяет наличие удаленного узла в сети(строит к нему путь), создает одну или несколько структур адресов сокета
                                                                  // localhost - официально зарезервированное доменное(символьное) имя для частных ip-адресов
	                                                              // второй параметр - порт, на котором слушается соединение
	                                                              // 3, 4 - указатели на структуру addrinfo
	                                                              // &addrResult содержит набор возможных сокетов, соединений, которые можно установить(распределился)
	if (result != 0)
	{
		cout << "Getaddrinfo failed with error: " << result << endl;
		WSACleanup(); // - деинициализация WSAStartup
		return 1;
	}

	ConnectSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);          //- создание сокета
		                                                                                                      //- фунция возвращает номер сокет-дескриптора
		                                                                                                      // 1 параметр - константа, семейство протоколов(лежит в addrResult)
		                                                                                                      // 2 параметр - тип протокола(лежит в ai_socktype)
																											  // 3 параметр - то, какой мы используем протокол(лежит в ai_protocolif (ConnectSocket == INVALID_SOCKET) // - проверка создания сокета(если не создался
	if(ConnectSocket == INVALID_SOCKET)
	{
		cout << "Socket creation  failed" << endl; 
		freeaddrinfo(addrResult);
		WSACleanup();
		return 1;
	}
	result = connect(ConnectSocket, addrResult->ai_addr, (int)addrResult->ai_addrlen);// - используется процессом-клиентом для установления связи с сервером(создание соединения)
	                                                                                  // 1 параметр - используемый сокет   
			                                                                          // 2 параметр - указатель на адрес сервера
		                                                                              // 3 параметр - длина сткуртуры адреса(целое число) 
	
	if (result == SOCKET_ERROR) // - проверка соединения с другой стороной(соединение не получилось)
	{
		cout << "Unable connect to server" << endl;
		closesocket(ConnectSocket); // - закрываем сокет
		ConnectSocket = INVALID_SOCKET; 
		freeaddrinfo(addrResult); // - освобождение памяти после распределения
		WSACleanup();
		return 1; // - так как не удалось соединиться
	}

	result = send(ConnectSocket, sendBuffer, (int)strlen(sendBuffer), 0); // - используется для записи данных в сокет, отправляет их в другой конец
		                                                                  // 1 параметр -  используемый сокет
				                                                          // 2 параметр - буфер, откуда мы берем данные(буфер - область памяти, используемая для временного хранения данных при вводе или выводе)
			                                                              // 3 параметр - длина данных(это строка, которую мы будем отправять)
		                                                                  // 4 параметр - флаг(если флаг = 0, то запись и считывание производится в порядке поступления байт)


	if (result == SOCKET_ERROR) 
	{
		cout << "Send failed, error: " << result << endl;
		closesocket(ConnectSocket); // - закрываем сокет
		freeaddrinfo(addrResult);   // - освобождение памяти после распределения
		WSACleanup();              
		return 1; 
	}
	cout << "Sent: " << result << " bytes" << endl; // - выводим переменнную result, так как функция send возвращает кол-во переданных данных, либо SOCKET_ERROR
	result = shutdown(ConnectSocket, SD_SEND); // - освобождение от отправки данных
	                                           // 1 параметр - сокет
	                                           // 2 параметр - каким образом выключить(SD_SEND - любые передачи запрещены, но прием доступен)
	if (result == SOCKET_ERROR) 
	{
		cout << "Shutdown error: " << result << endl;
		closesocket(ConnectSocket);
		freeaddrinfo(addrResult);
		WSACleanup();
		return 1;
	}

	do {                             // - прием данных до тех пор, пока не будет прервано соединение
		ZeroMemory(recvBuffer, 512); // - обнуление буфера

		result = recv(ConnectSocket, recvBuffer, 512, 0); // - используется для чтения данных из сокета
		                                                  // 1 параметр - сокет
		                                                  // 2 параметр - буфер, куда принимаем данные
		                                                  // 3 параметр - размер буфера(указывать максимальный)
			if (result > 0)                               // - в успешном случае
			{
	       cout << "Received " << result << " bytes " << endl; // - сколько данных полученно
		   cout << "Received data: " << recvBuffer << endl;   // - какие именно данные получены

            }   
			else if (result == 0) 
			{
				cout << "Connection closed" << endl;       // - отсутствие записанных в сокет даных
			}
			else if (result < 0)                           // - в случае ошибки
			{
				cout << "Recv failed with error" << endl;
			}
	} while (result > 0);
	closesocket(ConnectSocket);
	freeaddrinfo(addrResult);
	WSACleanup();
	return 0;


}
Editor is loading...
Leave a Comment