Click here to Skip to main content
13,731,474 members
Rate this:
 
Please Sign up or sign in to vote.
See more:
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();
	//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.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;

	// 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;
}


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.
Posted 7-Dec-17 9:46am
Updated 7-Dec-17 10:25am
v5
Comments
jeron1 7-Dec-17 16:19pm
   
Maybe update your original post with the change you implemented, it may help someone down the road.
pwasser 7-Dec-17 20:16pm
   
Or simply delete the question.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web06-2016 | 2.8.180920.1 | Last Updated 7 Dec 2017
Copyright © CodeProject, 1999-2018
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100