Page 1 of 1

Accepting Ethernet Connections

Posted: Wed Jan 05, 2011 4:28 pm
by SeeCwriter
The accept() function is a blocking function. Is there a non-blocking function I can use to accept an ethernet connection?

steve

Re: Accepting Ethernet Connections

Posted: Wed Jan 05, 2011 5:40 pm
by Ridgeglider
use listen() first. Lookup listen() in C:\nburn\docs\NetBurnerRuntimeLibrary\NetBurnerRuntimeLibraries.pdf
or see C:\nburn\examples\TCP\TcpServerSimple\main.cpp.

Here's also a code snippet from the example, and a flowchart from the NNDK manual:

Code: Select all

void TcpServerTask(void * pd)
{
    int ListenPort = (int) pd;

	// Set up the listening TCP socket
	int fdListen = listen(INADDR_ANY, ListenPort, 5);

	if (fdListen > 0)
	{
		IPADDR	client_addr;
		WORD	port;

		while(1)
		{
            // The accept() function will block until a TCP client requests
            // a connection. Once a client connection is accepting, the 
            // file descriptor fdnet is used to read/write to it. 
			iprintf( "Wainting for connection on port %d...\n", ListenPort );
			int fdnet = accept(fdListen, &client_addr, &port, 0);

			iprintf("Connected to: "); ShowIP(client_addr);
			iprintf(":%d\n", port);

			writestring(fdnet, "Welcome to the NetBurner TCP Server\r\n");
			char s[20];
			IPtoString(EthernetIP, s);
			siprintf(RXBuffer, "You are connected to IP Address %s, port %d\r\n", 
			                    s, TCP_LISTEN_PORT);
			writestring(fdnet, RXBuffer);

			while (fdnet > 0)
			{
				/* Loop while connection is valid. The read() function will return
				   0 or a negative number if the client closes the connection, so we
				   test the return value in the loop. Note: you can also use
				   ReadWithTimout() in place of read to enable the connection to
				   terminate after a period of inactivity. 
				*/
                int n = 0;
				do {
					n = read( fdnet, RXBuffer, RX_BUFSIZE );
					RXBuffer[n] = '\0';
					iprintf( "Read %d bytes: %s\n", n, RXBuffer );
				} while ( n > 0 );

				// Don't foreget to close !
				iprintf("Closing client connection: ");
				ShowIP(client_addr);
                iprintf(":%d\n", port);
				close(fdnet);
				fdnet = 0;
			} 
		} // while(1)
	} // while listen
}

Re: Accepting Ethernet Connections

Posted: Thu Jan 06, 2011 12:39 am
by thomastaranowski
I always have non-blocking server loops. This is entirely possible with the netburner, but not by using accept(). You need to use the ZeroWaitSelect() api.
What you need to do is call ZeroWaitSelect() with your listen socket in your receive FD_SET to listen for incoming connection requests. Once select() indicates rx is available on your listening socket, you can safely accept() without blocking.

The TcpMultiSocket example get's you most of the way there.

Your flow looks like the following:

while(1)
{
ZeroWaitSelect(max_fd, listen_fd_set, NULL, NULL);
if(listen fd is set in the listen_fd_set)
{
connection_fd = accept(listen_fd);
profit();
}

}