C++, клиент-серверное приложение на windows
пишу клиент-серверное приложение, захотел добавить функционал. 1.Клиент отправляет шифрованные данные на сервер. 2.Сервер принимает данные и отправляет их обратно клиенту. 3.Если данные совпали, то клиент отправляет оригинальные данные на сервер.
Но что-то не работает, данные приходят на сервер, а дальше он либо их не отправляет клиенту, либо клиент не может их грамотно считать.
Server.cpp
#define _WIN32_LEAN_AND_MEAN // требование Microsoft
#include <iostream>
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <thread>
#include <atomic>
#include <mutex>
#include <string>
#include <windows.h>
#include "decrypt.h"
#include "Servert.h"
#define SERVER_PORT "666"
#define BUFFER_SIZE 1024
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4005)
#pragma warning(disable:4101)
using std::cout;
using std::endl;
std::atomic<int> counter(0);
std::mutex mtx;
int check(SOCKET s)
{
if (s == SOCKET_ERROR)
{
cout << "Socket Error" << endl;
closesocket(s);
return 1;
}
return 0;
}
int ClientID()
{
mtx.lock();
++counter;
mtx.unlock();
return counter;
}
//обработка клиента
DWORD WINAPI HandleClient(LPVOID lpParam)
{
std::pair<SOCKET, int>* params = reinterpret_cast<std::pair<SOCKET, int>*>(lpParam);
SOCKET ClientSocket = params->first;
int ClientID = params->second;
char recvBuffer[BUFFER_SIZE];
int result;
int count_messange = 1;
do
{
ZeroMemory(recvBuffer, sizeof(recvBuffer));
result = recv(ClientSocket, recvBuffer, sizeof(recvBuffer), 0); // получаем информацию от клиентского сокета (шифрованные данные)
if (result > 0)
{
cout << "(" << count_messange << ") Client [" << ClientID << "]: SHA256 = " << recvBuffer << endl;
result = send(ClientSocket, recvBuffer, result, 0); // отправляем клиенту сообщение из Буффера
if (result == SOCKET_ERROR)
{
cout << "Failed to send data back" << endl;
check(ClientSocket);
return 1;
}
}
else if (result == 0)
{
cout << "Connection closing..." << endl;
}
else
{
cout << "Recv failed with error" << endl;
check(ClientSocket);
return 1;
}
++count_messange;
// получаем оригинальные данные от клиентского сокета
ZeroMemory(recvBuffer, sizeof(recvBuffer));
result = recv(ClientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (result > 0)
{
cout << "(" << count_messange << ") Client [" << ClientID << "]: original data = " << recvBuffer << endl;
// result = send(ClientSocket, recvBuffer, result, 0); // отправляем клиенту сообщение из Буффера
if (result == SOCKET_ERROR)
{
cout << "Failed to send data back" << endl;
check(ClientSocket);
return 1;
}
}
else if (result == 0)
{
cout << "Connection closing..." << endl;
}
else
{
cout << "Recv failed with error" << endl;
check(ClientSocket);
return 1;
}
} while (result > 0);
result = shutdown(ClientSocket, SD_SEND);
if (result == SOCKET_ERROR)
{
cout << "shutdown client socket failed" << endl;
check(ClientSocket);
return 1;
}
closesocket(ClientSocket);
return 0;
}
int main(int argc, char** argv)
{
WSADATA wsaData; // Версия текущей библиотеки Winsock 2.2
ADDRINFO hints; // продсказки для клиента о сервере
ADDRINFO* addrResult = NULL; // куда получим данные о сервере
SOCKET ClientSocket = INVALID_SOCKET; // Клиентский сокет
SOCKET ListenSocket = INVALID_SOCKET; // Слушающий сокет
const char* sendBuffer = "Your enter messange to server!"; // для сервера
char recvBuffer[BUFFER_SIZE];
int result; // код значения
result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
cout << "WSAStartup failed, resilt " << result << endl;
return 1;
}
cout << "----Server Activated----" << endl;
ZeroMemory(&hints, sizeof(hints)); // зануляем все поля hints (все параметры hints равны 0)
hints.ai_family = AF_INET; // ethernet
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; // протокол TCP/IP
hints.ai_flags = AI_PASSIVE; // информация для пассивной стороны (т.к сервер пассивная сторона, а клиент активная)
result = getaddrinfo(NULL, SERVER_PORT, &hints, &addrResult); // информация и сервере
if (result != 0)
{
cout << "getaddrinfo failed with error: " << result << endl;
WSACleanup();
return 1;
}
ListenSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
cout << "Socket creation failed" << endl;
freeaddrinfo(addrResult); // освобождаем addrResult
WSACleanup();
return 1;
}
result = bind(ListenSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
if (result == SOCKET_ERROR)
{
cout << "Binding socket failed" << endl;
check(ListenSocket);
freeaddrinfo(addrResult);
return 1;
}
result = listen(ListenSocket, SOMAXCONN); // второй параметр - сколько клиентов может слушать сервер
if (result != 0)
{
cout << "Listen socket failed" << endl;
check(ListenSocket);
freeaddrinfo(addrResult);
return 1;
}
cout << "Server listing on port: " << SERVER_PORT << endl;
while (true)
{
ClientSocket = accept(ListenSocket, NULL, NULL);
if (check(ClientSocket))
{
cout << "Accepting socket failed" << endl;
check(ListenSocket);
freeaddrinfo(addrResult);
return 1;
}
else
{
std::pair<SOCKET, int> parametrs = std::make_pair(ClientSocket, ClientID());
cout << "Client connected!" << endl;
HANDLE hThread = CreateThread(NULL, 0, HandleClient, ¶metrs, 0, NULL);
}
}
check(ClientSocket);
freeaddrinfo(addrResult);
closesocket(ListenSocket);
return 0;
}
----------------------------------------------------------------------------------
Client.cpp
#define _WIN32_LEAN_AND_MEAN // требование MS
#include <iostream>
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <windows.h>
#include "Clientt.h"
#include "encrypt.h"
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4005)
using namespace std;
void check(SOCKET& socket, ADDRINFO* addrResult)
{
closesocket(socket); // Закрываем соккет
socket = INVALID_SOCKET; // обнуляем
freeaddrinfo(addrResult);
}
int main()
{
WSADATA wsaData;
ADDRINFO hints; // продсказки для клиента о сервере
ADDRINFO* addrResult = NULL; // куда получим данные о сервере
SOCKET ConnectSocket = INVALID_SOCKET; // пока не создали соккет
int result = 0; // код значения
result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
cout << "WSAStartup failed, resilt " << result << endl;
return 1;
}
ZeroMemory(&hints, sizeof(hints)); // зануляем все поля hints (все параметры hints равны 0)
hints.ai_family = AF_INET; // ethernet
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; // протокол TCP/IP
result = getaddrinfo("localhost", "666", &hints, &addrResult); // информация и сервере
if (result != 0)
{
cout << "getaddrinfo failed with error: " << result << endl;
WSACleanup();
return 1;
}
ConnectSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
cout << "Socket creation failed" << endl;
freeaddrinfo(addrResult); // освобождаем addrResult
WSACleanup();
return 1;
}
result = connect(ConnectSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
if (result == SOCKET_ERROR)
{
cout << "Enable connect to server" << endl;
check(ConnectSocket, addrResult);
return 1;
}
char sendBuffer[512];
char recvBuffer[512];
int recvbuflen = sizeof(recvBuffer);
while (true) {
cout << "Enter message: ";
cin.getline(sendBuffer, sizeof(sendBuffer));
char* EncryptMessange= encrypt(sendBuffer);
cout << "Sending encrypted data..." << endl;
result = send(ConnectSocket, EncryptMessange, static_cast<int>(strlen(EncryptMessange)), 0); // отправляем серверу шифрованные данные
if (result == SOCKET_ERROR)
{
cout << "Send failed: " << WSAGetLastError() << endl;
check(ConnectSocket, addrResult);
WSACleanup();
return 1;
}
ZeroMemory(recvBuffer, sizeof(recvBuffer));
result = recv(ConnectSocket, recvBuffer, recvbuflen, 0);
if (result > 0)
{
cout << "Received: " << recvBuffer << endl;
ZeroMemory(recvBuffer, sizeof(recvBuffer));
}
else if (result == 0)
{
cout << "Connection closed by server." << endl;
break;
}
else
{
cout << "Receive failed: " << WSAGetLastError() << endl;
break;
}
if (result > 0)
{
if (equals(sendBuffer, recvBuffer))
{
cout << "Original data has been delivered: " << sendBuffer << endl;
ZeroMemory(recvBuffer, sizeof(recvBuffer));
ZeroMemory(sendBuffer, sizeof(sendBuffer));
continue;
}
else if (result == 0)
{
cout << "Connection closed by server." << endl;
break;
}
else
{
cout << "Recieve failed: " << WSAGetLastError() << endl;
break;
}
}
}
check(ConnectSocket, addrResult);
WSACleanup();
return 0;
}```