Click here to Skip to main content
13,766,484 members
Rate this:
 
Please Sign up or sign in to vote.
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 13-Jul-18 11:53am
Updated 15-Jul-18 3: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).
AntiRix 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.
AntiRix 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?
Richard MacCutchan 14-Jul-18 9:32am
   
You are asking me to guess what your code is doing; but I have no way of telling. You need to use your debugger to find out what the calling code is actually passing to the function.

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
Web01-2016 | 2.8.181114.1 | Last Updated 15 Jul 2018
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