Trying to make a TCP server, client connects and disconnects immediately

Gan via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Feb 5 16:15:14 PST 2015


I managed to get the client to connect but immediately on the 
server side, this happens:

long length = player.playerSocket.receive(buf);
		if (length == 0) { //No longer connected
			player.playerSocket.shutdown(SocketShutdown.BOTH);
			player.playerSocket.close();
		}

The player's socket receives a 0 length which means the 
connection is dead. Why does that happen?

Here's my full server-side networking code:

module server.networkingandio.networkingcontroller;
import server.server;
import server.player.player;

import std.socket;
import std.stdio;
import core.thread;
import std.range;
import std.traits;
import std.typecons;
import std.typetuple;
import std.algorithm;
import std.concurrency;

class NetworkingController
{
	Server server;

	Player[] players;

	TcpSocket socket;

	this(Server s)
	{
		server = s;
		players = new Player[](0);
		writeln("Server active on port 7777");

		socket = new TcpSocket();
		socket.bind(new InternetAddress(7777));
		socket.listen(100);
		socket.blocking = true;

		spawn(&handleNewConnectionsThread, cast(shared)socket);
	}
	void logic() {
		//Check for new sockets
		bool receivedNewSocket = true;
		while (receivedNewSocket) {
			receivedNewSocket = receiveTimeout(0.msecs,
				(shared NewConnectionMsg message) {
					NewConnectionMsg msg = cast(NewConnectionMsg)message;
					newConnection(msg.socket);
				},
				(shared ReceiveDataMsg message) {
					//Convert data to MessageReader, send to server message 
handler
				}
			);
		}

		//Check for dead sockets
		for (int i = 0; i < players.length; i++) {
			Player p = players[i];
			if (p.playerSocket.isAlive == false) {
				players = players.remove(i);
				i--;
				server.removeConnection(p);
			}
		}
		//Check for socket messages
	}
	void newConnection(Socket conn) {
		Player p = new Player(conn, this);
		players ~= p;
		server.newConnection(p);
		//Set up listener for player socket
		spawn(&handleReceiveDataThread, cast(shared)p);
	}
}
class NewConnectionMsg {
	Socket socket;
	this(Socket socket) {
		this.socket = socket;
	}
}
class ReceiveDataMsg {
	Player player;
	ubyte[] data;
	this(Player player, ubyte[] data) {
		this.player = player;
		this.data = data;
	}
}

void handleNewConnectionsThread(shared TcpSocket s) {
	Socket socket = cast(Socket)s;
	while(socket.isAlive) {
		Socket playerSocket = socket.accept();
		if (playerSocket !is null && playerSocket.isAlive == true) {
			playerSocket.blocking = true;
			ownerTid.send(cast(shared) new NewConnectionMsg(playerSocket));
		}
	}
	scope(exit)socket.close();
}

void handleReceiveDataThread(shared Player p) {
	Player player = cast(Player)p;
	while(player.playerSocket.isAlive) {
		ubyte[] buf = new ubyte[](0);
		long length = player.playerSocket.receive(buf);
		if (length == 0) { //No longer connected
			player.playerSocket.shutdown(SocketShutdown.BOTH);
			player.playerSocket.close();
		} else {
			ownerTid.send(cast(shared) new ReceiveDataMsg(player, buf));
		}
	}
	scope(exit)player.playerSocket.close();
}


More information about the Digitalmars-d-learn mailing list