Untitled
unknown
c_cpp
2 years ago
9.8 kB
9
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