User 13204940 Ответов: 0

Таинственный данных, получаемых


Привет
Решено: смотрите конец вопроса

Я написал простой сервер на 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]

Или просто удалите вопрос.

0 Ответов