Таинственный данных, получаемых
Привет
Решено: смотрите конец вопроса
Я написал простой сервер на C++, который просто прослушивает соединения, назначает класс ClientConnection каждому соединению, и эти сокеты получают сообщения. Когда мое отдельное клиентское приложение подключается к серверу, соединение подтверждается, но сервер считает, что он получает сообщение. Данные отправляются от моего клиента в формате, где первый байт-это длина данных (хотя на данный момент никаких данных не было отправлено), и сервер интерпретирует первый байт того, что он получает, как "-52".
Надеюсь, вы видите, что я сделал не так; он работал нормально, когда у меня был потоковый код Server.cpp но я перевел его в другое место. ClientConnection.cpp.
Сервер.ч
#pragma once #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <winsock.h> #include <vector> #include <sstream> #include "..\..\CPPUtils\CPPUtils\DebugUtils.h" #include "ClientConnection.h" class __declspec(dllexport) Server { public: Server(); ~Server(); //std::vector<ClientConnection*> clients; private: bool listening = false; int port = 1123; };
Server.cpp
#include "stdafx.h" #include "Server.h" #pragma comment(lib, "ws2_32.lib") Server::Server() { WSADATA wsaData; sockaddr_in server; SOCKET listenSocket; // start highest version of winsock if (WSAStartup(0x101, &wsaData) != 0) return; // fill winsock struct server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(port); // create listen socket listenSocket = socket(AF_INET, SOCK_STREAM, 0); if (listenSocket == INVALID_SOCKET) return; // bind socket to port if (bind(listenSocket, (sockaddr*)&server, sizeof(server)) != 0) return; // listen for a connection if (listen(listenSocket, 5) != 0) return; SOCKET clientSocket; sockaddr_in from; int fromlen = sizeof(from); while (true) { // accept connections clientSocket = accept(listenSocket, (struct sockaddr*)&from, &fromlen); //char ip_holder[16]; //sprintf_s(ip_holder, "%s", ((struct sockaddr_in*)&from)->sin_addr); //DebugUtils::msgbox("Server", "Client Connected from IP: ", ip_holder); DebugUtils::msgbox("Server", "Client Connected", ""); // create new thread and pass socket ClientConnection* newConn = new ClientConnection((LPVOID)socket); //clients.push_back(newConn); //delete newConn; } // shutdown winsock closesocket(listenSocket); WSACleanup(); } Server::~Server() { DebugUtils::msgbox("Debug", "Server dtor", ""); /*for (ClientConnection* conn : clients) { conn->disconnect(); delete conn; }*/ }
ClientConnection.ч
#pragma once #include <vector> #include <winsock.h> #include "..\..\CPPUtils\CPPUtils\ConversionUtils.h" #include "..\..\CPPUtils\CPPUtils\DebugUtils.h" #include <string> class __declspec(dllexport) ClientConnection { public: ClientConnection(LPVOID socket); ~ClientConnection(); void disconnect(); private: static DWORD WINAPI StartListenThread(void* str); void ListenThread(LPVOID socket); bool listening = false; };
ClientConnection.cpp
#include "stdafx.h" #include "ClientConnection.h" struct InstanceSocketStruct { ClientConnection* instance; LPVOID socket; InstanceSocketStruct(ClientConnection* instance, LPVOID socket) { this->instance = instance; this->socket = socket; } }; ClientConnection::ClientConnection(LPVOID socket) { CreateThread(NULL, 0, StartListenThread, new InstanceSocketStruct(this, socket), 0, NULL); } ClientConnection::~ClientConnection() { DebugUtils::msgbox("Debug", "ClientConnection dtor", ""); } DWORD WINAPI ClientConnection::StartListenThread(void* str) { InstanceSocketStruct* i_str = (InstanceSocketStruct*)str; i_str->instance->ListenThread(i_str->socket); return 0; } void ClientConnection::ListenThread(LPVOID socket) { SOCKET clientSocket = (SOCKET)socket; listening = true; // listen for data while (listening) { int error; char length_byte[1]; error = recv(clientSocket, length_byte, 1, 0); // read length byte Sleep(10); if (error == 0) { DebugUtils::msgbox("Debug", "Error is 0, closing socket and ending thread", ""); closesocket(clientSocket); ExitThread(0); } char packetID_byte[1]; recv(clientSocket, packetID_byte, 1, 0); // read packetID byte Sleep(10); int data_length = length_byte[0]; int packetID = packetID_byte[0]; DebugUtils::msgbox("Debug", "5:", std::to_string(data_length)); std::vector<char> data_bytes(data_length); recv(clientSocket, data_bytes.data(), data_length, 0); // read data Sleep(10); DebugUtils::msgbox("Debug", "6", ""); std::string data = std::string(data_bytes.begin(), data_bytes.end()); DebugUtils::msgbox("Debug", "Received data: ", data.c_str()); DebugUtils::msgbox("Debug", "7", ""); } DebugUtils::msgbox("Debug", "Exiting thread", ""); closesocket(clientSocket); ExitThread(0); } void ClientConnection::disconnect() { DebugUtils::msgbox("Debug", "disconnect", ""); // send message to client listening = false; }
РЕШЕННЫЙ:
Я сделал сумасшедшего. К сожалению, компилятор позволил мне сделать ошибку, поэтому я ее не увидел.
Решение состояло в том, чтобы измениться:
ClientConnection* newConn = new ClientConnection((LPVOID)socket);
к
ClientConnection* newConn = new ClientConnection((LPVOID)clientSocket);
Компилятор позволил мне ввести "сокет", поскольку это действительно имя функции, но не сокет, который я пытался передать.
Что я уже пробовал:
Сравнивая мой код с оригиналом, все кажется таким же
Вставив несколько точек отладки, сузил проблему до того, что сервер считает, что он получает данные откуда-то.
jeron1
Возможно, обновите свой первоначальный пост с помощью изменений, которые вы внедрили, это может помочь кому-то в будущем.
[no name]
Или просто удалите вопрос.