Re: PR_Poll() and non-blocking sockets?

Matt Lawson <[email protected]>
Newsgroups gmane.comp.mozilla.devel.nspr
Message-ID <[email protected]>
> Other than that, your description seems correct.  I'll
> need to look
> at your code snippets to see what's wrong.
> 
> Wan-Teh

OK I wrote a simplified program, but this one works as expected!  It seems the problem in my main application was that I was confusing the various sockets.  The poll would trigger on one, but then I would inadvertently read a different one, so the first one's data was still there, that's why it triggered every time.

Sorry to waste your time.  I have included the sample program in hopes that it may help someone else.

_______________________________________________
dev-tech-nspr mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-nspr
simple.cpp (text/plain, 2.5 KB)
#include <prio.h>
#include <prnetdb.h>
#include <prerror.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
	int rc,bytesAvail;
        PRPollDesc pollArray[1]; 
        PRIntervalTime timeout;
	PRFileDesc *listenSocket;
	PRFileDesc *incomingSocket;
	bool haveClient, done;
        PRStatus prResult;
        PRSocketOptionData thisOption;
	PRNetAddr listenAddr, incomingAddr;
	char readBuffer[512];

	haveClient=false;	// initially no client is connected

	timeout=PR_MillisecondsToInterval(200);	// 200 ms timeout

	// Create listener socket
	listenSocket = PR_NewTCPSocket();

	// Set listener socket to non-blocking
        thisOption.option = PR_SockOpt_Nonblocking;
	thisOption.value.non_blocking=1;

	prResult = PR_SetSocketOption(listenSocket, &thisOption);

	if (prResult==PR_SUCCESS) {
		printf("Listener socket set to non-blocking OK\n");
	} else {
		exit(1);
	}

	// Set listener socket address and port
	PR_InitializeNetAddr(PR_IpAddrAny, 11000, &listenAddr);

	// bind
	prResult=PR_Bind(listenSocket, &listenAddr);

	if (prResult==PR_SUCCESS) {
		printf("Bind OK\n");
	} else {
		exit(1);
	}

	// listen
	prResult=PR_Listen(listenSocket, 10);	// the 10 is arbitrary

	if (prResult==PR_SUCCESS) {
		printf("Listen OK\n");
	} else {
		exit(1);
	}

	done=false;

        while (!done) {
		// If the client is not connected, try to accept a new one
		if (!haveClient) {
			incomingSocket = PR_Accept(listenSocket, &incomingAddr, timeout);

			if (incomingSocket==NULL) {
				//printf("Incoming socket NULL\n");
			} else {
				printf("Incoming socket accepted OK\n");
				haveClient=true;
			}
		}

		// If a client has connected then we want to begin polling it
		if (haveClient) {

			pollArray[0].fd=incomingSocket;
			pollArray[0].in_flags=PR_POLL_READ;

			rc=PR_Poll(pollArray, 1, timeout);

			switch(rc) {
				case -1:
				// error
				printf("PR_Poll error: %d\n", PR_GetError());

				case 0:
				// timeout
				printf("PR_Poll timeout\n");
				break;

				default:
				// Some sockets indicate readable
				bytesAvail = PR_Available(incomingSocket);

				// Has the socket closed?
				printf("PR_Poll data ready: %d bytes\n",bytesAvail);
				if (bytesAvail==0) {
					printf("Client has closed\n");
					haveClient=false;
				}

				// Are there some bytes to read?
				if (bytesAvail>0) {
					rc=PR_Recv(incomingSocket, (void*) readBuffer, 500, 0, timeout);
					printf("%d bytes read\n",rc);
				}
				break;
			} // end switch
		} // end has a client
	} // end while not done
} // end main
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.