#include #include #include #include #include #include #include #include #include #include #define LOCALSOCK #ifdef LOCALSOCK #include #else #include #include #include #endif /*#define NOBLOCK*/ #ifdef NOBLOCK #include #endif #define SCHEDRT #ifdef SCHEDRT #include #endif #define MAX(a,b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a > _b ? _a : _b; }) #define MIN(a,b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a > _b ? _b : _a; }) #define NCLI 16 int sock_init () { #ifdef LOCALSOCK #define UNIX_PATH_MAX 108 #define SOCKPTH "/tmp/alt-dbus" /* connection oriented local socket that preserve * order and packet boundaries */ int s; struct sockaddr_un sockstr; sockstr.sun_family = AF_UNIX; memcpy (sockstr.sun_path, SOCKPTH, UNIX_PATH_MAX); if (-1 == (s = socket (PF_UNIX, SOCK_SEQPACKET, 0))) { perror ("socket"); return 0; } #else /* tcp sockets */ #define HOST 127.0.0.1 #define PORT 50101 int s; struct sockaddr_in sockstr; sockstr.sin_family = AF_INET; sockstr.sin_port = htons (PORT); sockstr.sin_addr.s_addr = INADDR_ANY; memset (sockstr.sin_zero, '\0', sizeof sockstr.sin_zero); if(-1 == (s = socket(PF_INET, SOCK_STREAM,0))) { perror("socket"); return 0; } #endif if (-1 == setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof (int))) { perror ("setsockopt"); return 0; } if (-1 == bind (s, (struct sockaddr *) &sockstr, sizeof (sockstr))) { perror ("bind"); return 0; } if (-1 == listen (s, 5)) { perror ("listen"); return 0; } return s; } int process (int i, char *buff) { if (buff[0] == 'i') { uint32_t *ptr = (void *) buff + 1; printf ("%d :: %d\n", i, ntohl (*ptr)); return 1; } return 0; } void main_loop (int scket) { static char rcvbuff[2048]; int clients[NCLI] = { 0 }; int i; int ret; fd_set master_set, work_set; int maxfd = scket; /*so far it's this one */ FD_ZERO (&work_set); FD_SET (scket, &work_set); master_set = work_set; while (-1 != select (maxfd + 1, &work_set, NULL, NULL, NULL)) { if (FD_ISSET (scket, &work_set)) { i = 0; while (i < sizeof clients / sizeof *clients && clients[i] > 0) i++; if (-1 == (clients[i] = accept (scket, NULL, NULL))) { perror ("accept"); continue; }; FD_SET (clients[i], &master_set); maxfd = MAX (clients[i], maxfd); } for (i = 0; i < sizeof clients / sizeof *clients; i++) { if (clients[i] && FD_ISSET (clients[i], &work_set)) { switch (recv (clients[i], rcvbuff, sizeof rcvbuff, 0)) { case -1: case 0: close (clients[i]); FD_CLR (clients[i], &master_set); clients[i] = 0; break; default: if(process (clients[i], rcvbuff)) { #ifndef LOCALSOCK setsockopt (clients[i], IPPROTO_TCP, TCP_NODELAY, (int[]){1}, sizeof (int)); setsockopt (clients[i], IPPROTO_TCP, TCP_CORK, (int[]){1}, sizeof (int)); #endif ret = send(clients[i],"ACK",4, #ifndef NOBLOCK 0 #else MSG_DONTWAIT #endif ); if(ret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) printf("send would block!\n"); #ifndef LOCALSOCK setsockopt (clients[i], IPPROTO_TCP, TCP_NODELAY, (int[]){0}, sizeof (int)); setsockopt (clients[i], IPPROTO_TCP, TCP_CORK, (int[]){0}, sizeof (int)); #endif } } } } work_set = master_set; } //shouldn't happen perror ("select"); for (i = 0; i < sizeof clients / sizeof *clients; i++) { if (clients[i] > 0) { close (clients[i]); } } close (scket); } int main () { #ifdef SCHEDRT struct sched_param parms; parms.sched_priority = 5; sched_setscheduler(0,SCHED_FIFO,&parms); #endif int scket; scket = sock_init (); if (scket > 0) main_loop (scket); return EXIT_SUCCESS; }