Untitled
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