#include "net_mod_server_socket.h" #include "socket_io.h" #include "net_mod_socket_io.h" NetModServerSocket::NetModServerSocket(int port, ShmModSocket * modsocket): shm_mod_socket(modsocket) { char portstr[32]; sprintf(portstr, "%d", port); listenfd = Open_listenfd(portstr); init_pool(listenfd); } NetModServerSocket::~NetModServerSocket() { Close(listenfd); } void NetModServerSocket::start() { int connfd; socklen_t clientlen; struct sockaddr_storage clientaddr; while (1) { /* Wait for listening/connected descriptor(s) to become ready */ pool.ready_set = pool.read_set; pool.nready = select(pool.maxfd + 1, &pool.ready_set, NULL, NULL, NULL); /* If listening descriptor ready, add new client to pool */ if (FD_ISSET(listenfd, &pool.ready_set)) { clientlen = sizeof(struct sockaddr_storage); connfd = accept(listenfd, (SA *)&clientaddr, &clientlen); add_client(connfd); } /* Echo a text line from each ready connected descriptor */ check_clients(); } } void NetModServerSocket::init_pool(int listenfd) { /* Initially, there are no connected descriptors */ int i; pool.maxi = -1; //line:conc:echoservers:beginempty for (i = 0; i < FD_SETSIZE; i++) pool.clientfd[i] = -1; //line:conc:echoservers:endempty /* Initially, listenfd is only member of select read set */ pool.maxfd = listenfd; //line:conc:echoservers:begininit FD_ZERO(&pool.read_set); FD_SET(listenfd, &pool.read_set); //line:conc:echoservers:endinit } /* $begin add_client */ void NetModServerSocket::add_client(int connfd) { int i; pool.nready--; for (i = 0; i < FD_SETSIZE; i++) /* Find an available slot */ if (pool.clientfd[i] < 0) { /* Add connected descriptor to the pool */ pool.clientfd[i] = connfd; //line:conc:echoservers:beginaddclient Rio_readinitb(&pool.clientrio[i], connfd); //line:conc:echoservers:endaddclient /* Add the descriptor to descriptor set */ FD_SET(connfd, &pool.read_set); //line:conc:echoservers:addconnfd /* Update max descriptor and pool highwater mark */ if (connfd > pool.maxfd) //line:conc:echoservers:beginmaxfd pool.maxfd = connfd; //line:conc:echoservers:endmaxfd if (i > pool.maxi) //line:conc:echoservers:beginmaxi pool.maxi = i; //line:conc:echoservers:endmaxi break; } if (i == FD_SETSIZE) /* Couldn't find an empty slot */ err_msg(errno, "add_client error: Too many clients"); } /* $end add_client */ /* $begin check_clients */ void NetModServerSocket::check_clients() { int i, connfd, n; char buf[MAXLINE]; rio_t rio; for (i = 0; (i <= pool.maxi) && (pool.nready > 0); i++) { connfd = pool.clientfd[i]; rio = pool.clientrio[i]; /* If the descriptor is ready, echo a text line from it */ if ((connfd > 0) && (FD_ISSET(connfd, &pool.ready_set))) { pool.nready--; if ((n = rio_readpkgb(&rio, buf, MAXLINE)) > 0) { Rio_writen(connfd, buf, n); Rio_writen(connfd, PKG_SEP, strlen(PKG_SEP)); // shm_mod_socket->sendto(buf, n, msg->key); // net_mod_msg_t *msg = (net_mod_msg_t*)buf; // if(msg.mod == PUB_SUB) { // shm_mod_socket->pub(msg->topic, msg->topic_size, msg->content, msg->content_size, msg->key); // } else { // shm_mod_socket->sendto(msg->buf, msg->size, msg->key); // } } /* EOF detected, remove descriptor from pool */ else { Close(connfd); //line:conc:echoservers:closeconnfd FD_CLR(connfd, &pool.read_set); //line:conc:echoservers:beginremove pool.clientfd[i] = -1; //line:conc:echoservers:endremove } } } }