Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 06, 2015 Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
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(); } |
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On Friday, 6 February 2015 at 00:15:15 UTC, Gan wrote:
> ubyte[] buf = new ubyte[](0);
This is your problem: receive fills a preexisting buffer, and you allocated zero bytes for it to fill, so it can't give you anything.
Give it a bigger buffer, I like to use 4096, and it will work better.
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Friday, 6 February 2015 at 00:24:54 UTC, Adam D. Ruppe wrote:
> On Friday, 6 February 2015 at 00:15:15 UTC, Gan wrote:
>> ubyte[] buf = new ubyte[](0);
>
> This is your problem: receive fills a preexisting buffer, and you allocated zero bytes for it to fill, so it can't give you anything.
>
> Give it a bigger buffer, I like to use 4096, and it will work better.
Will there ever be a message bigger than 4096 bytes?
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On Friday, 6 February 2015 at 00:28:00 UTC, Gan wrote:
> On Friday, 6 February 2015 at 00:24:54 UTC, Adam D. Ruppe wrote:
>> On Friday, 6 February 2015 at 00:15:15 UTC, Gan wrote:
>>> ubyte[] buf = new ubyte[](0);
>>
>> This is your problem: receive fills a preexisting buffer, and you allocated zero bytes for it to fill, so it can't give you anything.
>>
>> Give it a bigger buffer, I like to use 4096, and it will work better.
>
> Will there ever be a message bigger than 4096 bytes?
Or am I misunderstanding the receive function? Does it send whole messages or just message chunks?
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On Friday, 6 February 2015 at 00:31:37 UTC, Gan wrote:
> Or am I misunderstanding the receive function? Does it send whole messages or just message chunks?
It sends as much as it can when you call it. So if there's only 12 bytes available when you send it with a 4096 buffer, it will fill the first twelve bytes (and return 12) so you can slice it buffer[0 .. returnedValue] to get the data.
If there's more available than the buffer will hold, that data will be held on to until next time you call receive. If 5000 bytes come off the network, it will return 4096 the first time, then next time through the loop, it will return the remaining 904.
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Friday, 6 February 2015 at 00:35:12 UTC, Adam D. Ruppe wrote:
> On Friday, 6 February 2015 at 00:31:37 UTC, Gan wrote:
>> Or am I misunderstanding the receive function? Does it send whole messages or just message chunks?
>
> It sends as much as it can when you call it. So if there's only 12 bytes available when you send it with a 4096 buffer, it will fill the first twelve bytes (and return 12) so you can slice it buffer[0 .. returnedValue] to get the data.
>
> If there's more available than the buffer will hold, that data will be held on to until next time you call receive. If 5000 bytes come off the network, it will return 4096 the first time, then next time through the loop, it will return the remaining 904.
How can you distinguish between different packets that get sent? Won't they all be merged to a giant blob of data?
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On Friday, 6 February 2015 at 00:50:43 UTC, Gan wrote:
> How can you distinguish between different packets that get sent? Won't they all be merged to a giant blob of data?
Yeah, that's normal in TCP though, because it is a stream oriented protocol. You could add stuff to your data indicating message length though.
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On 2/6/2015 9:50 AM, Gan wrote:
> On Friday, 6 February 2015 at 00:35:12 UTC, Adam D. Ruppe wrote:
>> On Friday, 6 February 2015 at 00:31:37 UTC, Gan wrote:
>>> Or am I misunderstanding the receive function? Does it send whole
>>> messages or just message chunks?
>>
>> It sends as much as it can when you call it. So if there's only 12
>> bytes available when you send it with a 4096 buffer, it will fill the
>> first twelve bytes (and return 12) so you can slice it buffer[0 ..
>> returnedValue] to get the data.
>>
>> If there's more available than the buffer will hold, that data will be
>> held on to until next time you call receive. If 5000 bytes come off
>> the network, it will return 4096 the first time, then next time
>> through the loop, it will return the remaining 904.
>
> How can you distinguish between different packets that get sent? Won't
> they all be merged to a giant blob of data?
You need to give each of your packets a header. At a minimum you'll want a message ID and message length. When a message comes in, you use the length field to determine where one packet ends and the next one begins.
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Friday, 6 February 2015 at 01:36:17 UTC, Mike Parker wrote:
> On 2/6/2015 9:50 AM, Gan wrote:
>> On Friday, 6 February 2015 at 00:35:12 UTC, Adam D. Ruppe wrote:
>>> On Friday, 6 February 2015 at 00:31:37 UTC, Gan wrote:
>>>> Or am I misunderstanding the receive function? Does it send whole
>>>> messages or just message chunks?
>>>
>>> It sends as much as it can when you call it. So if there's only 12
>>> bytes available when you send it with a 4096 buffer, it will fill the
>>> first twelve bytes (and return 12) so you can slice it buffer[0 ..
>>> returnedValue] to get the data.
>>>
>>> If there's more available than the buffer will hold, that data will be
>>> held on to until next time you call receive. If 5000 bytes come off
>>> the network, it will return 4096 the first time, then next time
>>> through the loop, it will return the remaining 904.
>>
>> How can you distinguish between different packets that get sent? Won't
>> they all be merged to a giant blob of data?
>
> You need to give each of your packets a header. At a minimum you'll want a message ID and message length. When a message comes in, you use the length field to determine where one packet ends and the next one begins.
Oh sweet. Though if one message length is off by even 1 byte, then all future messages get corrupted?
|
February 06, 2015 Re: Trying to make a TCP server, client connects and disconnects immediately | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gan | On 2015-02-05, 8:17 PM, Gan wrote:
> On Friday, 6 February 2015 at 01:36:17 UTC, Mike Parker wrote:
>> On 2/6/2015 9:50 AM, Gan wrote:
>>> On Friday, 6 February 2015 at 00:35:12 UTC, Adam D. Ruppe wrote:
>>>> On Friday, 6 February 2015 at 00:31:37 UTC, Gan wrote:
>>>>> Or am I misunderstanding the receive function? Does it send whole
>>>>> messages or just message chunks?
>>>>
>>>> It sends as much as it can when you call it. So if there's only 12
>>>> bytes available when you send it with a 4096 buffer, it will fill the
>>>> first twelve bytes (and return 12) so you can slice it buffer[0 ..
>>>> returnedValue] to get the data.
>>>>
>>>> If there's more available than the buffer will hold, that data will be
>>>> held on to until next time you call receive. If 5000 bytes come off
>>>> the network, it will return 4096 the first time, then next time
>>>> through the loop, it will return the remaining 904.
>>>
>>> How can you distinguish between different packets that get sent? Won't
>>> they all be merged to a giant blob of data?
>>
>> You need to give each of your packets a header. At a minimum you'll
>> want a message ID and message length. When a message comes in, you use
>> the length field to determine where one packet ends and the next one
>> begins.
>
> Oh sweet. Though if one message length is off by even 1 byte, then all
> future messages get corrupted?
Yep. You're using a reliable stream-based protocol. If you want discrete messages, you can use UDP. Though it is an unreliable packet-oriented protocol. Don't foul up your message lengths....
|
Copyright © 1999-2021 by the D Language Foundation