A bit of socket programming... what if the meta is responding, but returns nothing?

Bug reports and discussion about bugs.
Post Reply
User avatar
PowerWyrm
Posts: 241
Joined: Sat Jan 09, 2010 4:28 pm

A bit of socket programming... what if the meta is responding, but returns nothing?

Post by PowerWyrm »

Here's an interesting problem that's currently happening with the MAngband metaserver: it is responding (you can ping, create a socket and connect), but returns nothing when you try to receive data. Since the TomeNET code is identical (at least for Windows), this could happen also with TomeNET.

Symptom: when launching the client, you get "Connecting to metaserver..." message, but then the client hangs forever.
Workaround: modify your ini file and uncomment (or add) the "host=..." line to connect to a server manually (in case of TomeNET, you also have the convenient "TomeNET direct" executable).

Now a bit of code (from net-win.c)... To connect to the meta, the client calls CreateClientSocket(), checks for failure (in this case, defaults to asking to enter a server name manually), and calls SocketRead() to validate the connection. Our problem here is that CreateClientSocket() succeeds, but SocketRead() fails and waits indefinitely.

So we need to find a way to tell the client that the socket is opened, but unable to send data. Would a call to SocketReadable() work?
User avatar
PowerWyrm
Posts: 241
Joined: Sat Jan 09, 2010 4:28 pm

Re: A bit of socket programming... what if the meta is responding, but returns nothing?

Post by PowerWyrm »

Alright I've found a fix for the problem. You simply need to replace (in c-birth.c):

Code: Select all

	/* Read */
	bytes = SocketRead(socket, buf, 80192);
by:

Code: Select all

int bytes = 0;
int retries;
...

    /* Listen for reply (try ten times in ten seconds) */
    for (retries = 0; retries < 10; retries++)
    {
        /* Set timeout */
        SetTimeout(1, 0);

        /* Wait for info */
        if (!SocketReadable(socket)) continue;

        /* Read */
        bytes = SocketRead(socket, buf, 80192);
        break;
    }
Tested with the TomeNET meta (data is returned) and the MAngband meta (timeout triggered, default to manually selecting a server).
Post Reply