summaryrefslogblamecommitdiffstats
path: root/select/test.c
blob: 63f1986aa72ce785044c24dfda4c828f6b2c4c59 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                            










                               
                       




                             

                                  
           
                                


                                           
                          
                        
 
























                                                                                      
                                                                                  




















                                                                            


                                          








































                                                                                      









                                                               




                               
/*
 * Test RTEMS networking
 *
 * This program may be distributed and used for any purpose.
 * I ask only that you:
 *      1. Leave this author information intact.
 *      2. Document any changes you make.
 *
 * W. Eric Norum
 * Saskatchewan Accelerator Laboratory
 * University of Saskatchewan
 * Saskatoon, Saskatchewan, CANADA
 * eric@skatter.usask.ca
 */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <rtems/error.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>

#define BASE_PORT	24742
#define CLIENT_COUNT	2

static int clientfd[CLIENT_COUNT];

static void
getClients (unsigned short port)
{
	int s, s1;
	struct sockaddr_in myAddr, farAddr;
	socklen_t addrlen;
	int clientCount;

	printf ("Create socket.\n");
	s = socket (AF_INET, SOCK_STREAM, 0);
	if (s < 0)
		rtems_panic ("Can't create socket: %s", strerror (errno));
	myAddr.sin_family = AF_INET;
	myAddr.sin_port = htons (port);
	myAddr.sin_addr.s_addr = INADDR_ANY;
	memset (myAddr.sin_zero, '\0', sizeof myAddr.sin_zero);
	printf ("Bind socket.\n");
	if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
		rtems_panic ("Can't bind socket: %s", strerror (errno));
	printf ("Listen.\n");
	if (listen (s, 2) < 0)
		rtems_panic ("Can't listen on socket: %s", strerror (errno));

	/*
	 * Accumulate clients
	 */
	for (clientCount = 0 ; clientCount < CLIENT_COUNT ; clientCount++) {
		printf ("Accept.\n");
		addrlen = sizeof farAddr;
		s1 = accept (s, (struct sockaddr *)&farAddr, &addrlen);
		if (s1 < 0)
			rtems_panic ("Can't accept connection: %s", strerror (errno));
		else
			printf ("ACCEPTED:%X\n", ntohl (farAddr.sin_addr.s_addr));
		clientfd[clientCount] = s1;
	}

	close (s);
}

static void
echoServer (unsigned short port)
{
	fd_set clientfdset;
	int clientCount;
	int topfd = 0;

	getClients (port);

	FD_ZERO (&clientfdset);

	for (clientCount = 0 ; clientCount < CLIENT_COUNT ; clientCount++) {
		int s1;

		s1 = clientfd[clientCount];
		FD_SET (s1, &clientfdset);
		if (s1 > topfd)
			topfd = s1;
	}

	/*
	 * Run clients
	 */
	for (;;) {
		fd_set readfdset;
		struct timeval tv;
		int n;
		int i;

		tv.tv_sec = 5;
		tv.tv_usec = 0;
		readfdset = clientfdset;
		n = select (topfd + 1, &readfdset, NULL, NULL, &tv);
		if (n < 0) {
			printf ("Select() error: %s\n", strerror (errno));
			return;
		}
		if (n == 0) {
			printf ("Timeout\n");
			continue;
		}
	
		printf ("Activity on %d file descriptor%s.\n", n, n == 1 ? "" : "s");
		for (i = 0 ; n && (i < CLIENT_COUNT) ; i++) {
			int fd = clientfd[i];
			if (FD_ISSET (fd, &readfdset)) {
				char buf[200];
				int nread;

				printf ("Activity on file descriptor %d.\n", fd);
				n--;
				nread = read (fd, buf, sizeof buf);
				if (nread < 0) {
					printf ("Read error %s.\n", strerror (errno));
					return;
				}
				if (nread == 0) {
					printf ("EOF\n");
					FD_CLR (fd, &clientfdset);
					close (fd);
					if (--clientCount == 0)
						return;
				}
				printf ("Read %d.\n", nread);
			}
		}
	}
}

void
doSocket (void)
{
	echoServer (BASE_PORT);
}