Click here to Skip to main content
15,888,082 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I've juggled this previously-working code around a bit to get it working for my implementation but now recv is returning -1 and is crashing my program.

You'll probably be able to spot the issue straight away but I've been staring at this screen for hours and I just cannot figure it out.

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <vector>
#include "Player.h"

#pragma comment(lib, "Ws2_32.lib")

std::vector<Player> players;

int main()
{
	printf("Server started\r\n");

	SOCKET connection_socket;
	
	WSADATA wsaData;
	sockaddr_in server;

	// start winsock
	int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);

	if (ret != 0) return 0;

	// fill in winsock struct ... 
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(123);

	connection_socket = socket(AF_INET, SOCK_STREAM, 0);

	if (connection_socket == INVALID_SOCKET) return 0;

	// bind our socket to a port(port 123) 
	if (bind(connection_socket, (sockaddr*)&server, sizeof(server)) != 0) return 0;
	// listen for a connection  
	if (listen(connection_socket, 5) != 0) return 0;

	// socket that we send and receive data on
	SOCKET client;

	sockaddr_in from;
	int fromlen = sizeof(from);

	// loop forever 
	while (true)
	{
		// accept connections
		client = accept(connection_socket, (struct sockaddr*)&from, &fromlen);
		printf("Client connected\r\n");

		Player p;
		PlayerConnection* connection = new PlayerConnection();
		connection->init(client);
		p.init(connection);
		players.push_back(p);
	}

	closesocket(connection_socket);
	WSACleanup();

	return 0;
}
#include "stdafx.h"
#include "PlayerConnection.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <vector>
#include <iostream>

struct ThreadData
{
	PlayerConnection* instance;
	SOCKET& socket;
};

DWORD WINAPI ThreadProcedure(LPVOID lpParam)
{
	ThreadData* data = (ThreadData*)lpParam;
	PlayerConnection* instance = data->instance;
	SOCKET socket = data->socket;

	char buf[100];
	int res;

	// if buffer = 'hello': strstr(buf, "hello")

	// receive messages
	while (true)
	{
		res = recv(socket, buf, sizeof(buf), 0); // read data

		Sleep(10);
		printf("res: %i\n", res);
		if (res <= 0)
		{
			printf("EXITING THREAD");
			closesocket(socket);
			ExitThread(0);
		}

		if (strstr(buf, "exit"))
		{
			instance->disconnect();
		}
		else
		{
			printf("Client said: %s\n", buf);
			Sleep(10);

			char txbuf[100];
			strcpy_s(txbuf, "You said: ");
			strcat_s(txbuf, buf);
			instance->send_message(txbuf);
		}

		strcpy_s(buf, "");
	}

	return 0;
}

void PlayerConnection::init(SOCKET& socket)
{
	this->socket = socket;

	ThreadData td = { this, socket };
	HANDLE threadHandle = CreateThread(NULL, 0, ThreadProcedure, &td, 0, NULL);
}

void PlayerConnection::send_message(char* buf)
{
	send(socket, buf, strlen(buf), 0);
}

void PlayerConnection::disconnect()
{
	closesocket(socket);
	ExitThread(0);
}


What I have tried:

I was thinking it might be an issue to do with either accessing objects created on the main thread from this new thread, but even if I directly pass the socket to the method, it doesn't even work using that.
Posted
Updated 15-Jul-18 2:31am
v3
Comments
Jochen Arndt 13-Jul-18 17:14pm    
RTFM: recv function:
"Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError."

That is the first thing to do when a function fails:
Get and report the error code (and optionally the corresponding error message).
[no name] 13-Jul-18 17:37pm    
Ok the issue I'm having now is that the code just stops running at one point and the program exits. I've narrowed down the issue but it still makes no sense.

DWORD WINAPI ThreadProcedure(LPVOID lpParam)
{
printf("ThreadProcedure begin\n");
ThreadData* data = (ThreadData*)lpParam;
printf("Got data\n");
PlayerConnection* instance = data->instance;
printf("Got instance\n");
SOCKET socket = data->socket;
printf("Got socket\n");

It outputs as far as "Got data", but then the program exits. It can't deal with data->instance for some reason
Richard MacCutchan 14-Jul-18 3:23am    
You print “Got data”, but you have not checked that what you get is a valid pointer. You must verify that lpParam is an actual data pointer, so go back to where this function is being called. From your previous questions on this issue there seems to be a lot of confusion about pointers.
Richard MacCutchan 14-Jul-18 3:35am    
You did not check that data is a valid pointer, which it obviously is not. From this and your previous questions it seems you still have a lot of misunderstanding about pointers. And you complicate matters further by trying to use them between threads and classes.
[no name] 14-Jul-18 5:49am    
Why would it not be a valid pointer? Is it the case that this code is run several times, sometimes having invalid data which I need to ignore, and other times having valid data?

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900