sockets question

Hi, all -

I'm really new to sockets, so please forgive me if this question is painfully simple.

I've written an app that, among other things, accepts a telnet connection (made via the "telnet" command from a terminal) and converses with it. I'd like to make this work so that only one client at a time can connect. Currently, when a second user tries to connect, the incoming messages get mixed up and lots of unpredictable results ensue.

Can someone point me in the right direction on how to lock out any subsequent connection attempts when someone already has a connection?

Thanks.

Oh, this is running SMX, not UNIX, but it has a very UNIX-like socket programming interface.
Last edited on
Can someone point me in the right direction on how to lock out any subsequent connection attempts when someone already has a connection?

I don't really get the question. If you don't want to accept any new connections, just stop calling accept().
Have some method that listens for connections until a successful connection is made. After that stop listening for incoming connections until the current one is terminated (by either end).

Also, might look into SSH. Telnet is super old and unsecure.
If you want only one user to connect, just call accept only once other than put it in a loop.

If you want to handle multiple clients, you may use function select()
It sounds like he's using a connectionless protocol (UDP) rather than TCP as the server gets all traffic form anyone, but it doesn't make sense becuase he's connecting over TCP with telnet.

mzimmers you will have to be more explicit about what you have (maybe post the code) before anyone can help.
Hey, guys -

Sorry I'm so late in responding...a million balls in the air right now. I appreciate the helpfulness, though.

I am indeed using TCP. My code follows the sequence on the server side of this diagram:

http://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/InternetSocketBasicDiagram_zhtw.png/420px-InternetSocketBasicDiagram_zhtw.png

So, one problem is, when one client has engaged the server, and another user tries to access it, telnet just echoes whatever he types in. I suppose, though, that this is the nature of telnet, and there's not much I can do about it.

But, when the first client has finished, the second client can't always get in, despite the fact that my server returns to the accept() call. (it works fine when someone tries to get in *after* the first user is finished.) I was wondering whether somehow, the second user, even though he can't connect, could somehow be confusing the server. And if so, is there a way to clear out any old stuff before calling accept() again?

And, ResidentBiscuit: I'm not married to telnet at all, but I don't know enough about SSH to do anything with it. Plus, the less stuff that the app depends on the client side having, the better off we are. But if you know of a good online tutorial for SSH that I could use, feel free to so advise me.

Thanks again...
I'm assuming you're just working on server side? Because client side will (under *nix, and SSH/Telnet clients are easy to get under windows) already have everything necessary. Telnet isn't always bad, if you're working in a highly trusted network (ie not connected to the Internet) then telnet is fine. It's lightweight and simple. But if you're connecting to something across the Internet or a device that is connected to the Internet, then go with SSH. There are many ssh libraries out there, this one tends to get recommended a lot:

http://www.libssh2.org/

OK, here's the source code that isn't working quite right. This is the first time I've ever played with socket I/O, so I'm sure it's far from optimal. It began as an example I found on the web.

First, the functions that read and write lines to the socket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
ssize_t Readline(int sockd, string &vptr, size_t maxlen)
{
    ssize_t n, rc = 0;
    char    c, buffer[MAX_LINE], *pBuf;
    pBuf = buffer;

	n = 0;
	while (n < maxlen)
{
        if ( (rc = readsocket(sockd, &c, 1)) == 1 )
        {
            if ( c == '\n')
                break;			// line break.
			else if (c == '\r')
				;				// do nothing (for SMX).
			else if (c == '\b') // backspace
			{
				if (n)
				{
					--pBuf;
					--n;
					writeBackspace(sockd);
				}			
 	    	}
			else
			{
				c = toupper(c);
				n++;
			    *pBuf++ = c;
			}
		}
        else
		{
			Nprintf("Readline: error %d.\n", errno);
			rc = -1;		// need to signal an error to caller.
			break;
        }
    }

	if (rc >= 0)	// if we had any successful reads,
	{
	    *pBuf = '\0';
		vptr = buffer;
		rc = n;		// return the length of the string we read.
	}

    return rc;
}

//  Write a line to a socket.
// returns 0 if successful; -1 if failed.
ssize_t Writeline(int sockd, string &vptr, size_t n)
{
    size_t      nleft;
    ssize_t     nwritten;
    static	char        *buffer;

    buffer = (char *) vptr.c_str();
    nleft  = n;
	ssize_t	rc = 0;
	
    while ( nleft > 0 )
    {

        if ( (nwritten = writesocket(sockd, buffer, nleft)) <= 0 )
       {
	        rc = -1;
			Nprintf("writesocket failed.\n");
			break;
        }
        nleft  -= nwritten;
        buffer += nwritten;
    }
    return rc;
}


readsocket() and writesocket are the SMX equivalents to the UNIX read() and write() functions.
Last edited on
And here's the section of the code that calls the above functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
	while (1)
	{
		rc = rcRead = rcWrite = 0;	// reset from any errors below.
		while ((conn_s = accept(list_s, NULL, NULL)) < 0 )
		{
			logError("telnetServer: Error calling accept()\n");
			smx_DelayMsec(5000);
		}
		
		// loop to read client requests and respond.
		// remain in this loop as long as reads and writes are OK;
		// go back to the acceptance wait.
		while (rcRead >= 0 && rcWrite == 0)
		{
			// Retrieve an input line from the connected socket
			
			rcWrite = Writeline(conn_s,
						   prompt,
						   prompt.length());
			
			rcRead = Readline(conn_s,
						  buffer,
						  MAX_LINE-1);
			
			// if the read was successful (and non-empty),
			// process the input and compose a reply.
			if (rcRead > 0)
			{
				if (rc == CMD_BYE) 	// got the "BYE" command
				{
					break;
				}
				rc = processInput(buffer);
				rcWrite = Writeline(conn_s,
									buffer,
									buffer.length());
				if (rcWrite != 0)
					break;
			}
			else if (rcRead == 0) // null line
			{
				buffer = LINE_BRK;
				rcWrite = Writeline(conn_s,
									buffer,
									buffer.length());
				if (rcWrite != 0)
					break;
			}
			else if (rcRead < 0)
			{
				// if we get to here in the code,
				// it probably means the client process died,
				// so this write might generate an socket error.
				buffer = "ENCOUNTERED I/O ERROR; TERMINATING.";
				buffer += LINE_BRK;
				Writeline(conn_s,
						  buffer,
						  buffer.length());
				break;
			}
		}
		closesocket(conn_s);
	}
}
Topic archived. No new replies allowed.