Hi
SOLVED: See end of question
I've written a simple server in C++ which simply listens for connections, assigns a ClientConnection class to each connection, and those sockets receive messages. When my separate client app connects to the server, the connection is acknowledged but the server believes it's receiving a message. Data is sent from my client in a format where the first byte is the data length, (even though no data has been sent at this point) and the server interprets the first byte of what it's receiving to be '-52'.
Hopefully you can see what I've done wrong; it was working fine when I had the threading code in Server.cpp but I moved it to ClientConnection.cpp.
Server.h
#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();
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;
if (WSAStartup(0x101, &wsaData) != 0) return;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET) return;
if (bind(listenSocket, (sockaddr*)&server, sizeof(server)) != 0) return;
if (listen(listenSocket, 5) != 0) return;
SOCKET clientSocket;
sockaddr_in from;
int fromlen = sizeof(from);
while (true)
{
clientSocket = accept(listenSocket, (struct sockaddr*)&from, &fromlen);
DebugUtils::msgbox("Server", "Client Connected", "");
ClientConnection* newConn = new ClientConnection((LPVOID)socket);
}
closesocket(listenSocket);
WSACleanup();
}
Server::~Server()
{
DebugUtils::msgbox("Debug", "Server dtor", "");
}
ClientConnection.h
#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;
while (listening)
{
int error;
char length_byte[1];
error = recv(clientSocket, length_byte, 1, 0);
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);
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);
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", "");
listening = false;
}
SOLVED:
I did a derp. Unfortunately the compiler allowed me to make a mistake so I didn't see it.
The solution was to change:
ClientConnection* newConn = new ClientConnection((LPVOID)socket);
to
ClientConnection* newConn = new ClientConnection((LPVOID)clientSocket);
The compiler allowed me to type "socket" as that is indeed the name of a function, but not the socket I was trying to pass.
What I have tried:
Comparing my code to the original, everything seems the same
Inserting several debug points, narrowed the issue down to be that the server believes it's receiving data from somewhere.