void timeout_cb(EV_P_ ev_timer *watcher, int revents) { struct conn_ctx *conn_ctx = (struct conn_ctx*) (((void *)watcher) - sizeof(ev_io)); struct conn *local = conn_ctx->conn; struct conn *remote = local->another; if(debug) printf("server time out, close fd %d and %d\n", local->fd, remote->fd); ev_timer_stop(EV_A_ watcher); close_and_free(EV_A_ local); close_and_free(EV_A_ remote); }
void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) { struct conn_ctx *conn_ctx = (struct conn_ctx*) (((void *)watcher) - sizeof(ev_io)); struct conn *remote = conn_ctx->conn; struct conn *local = remote->another; if(debug) printf("remote time out, close socket %d and %d\n", local->fd, remote->fd); ev_timer_stop(EV_A_ watcher); if(local != NULL) close_and_free(EV_A_ local); if(remote != NULL) close_and_free(EV_A_ remote); }
void *computing(void *argument) { static connections *my_data; my_data= (connections *) argument; char *buffer=my_data->buf; int state = my_data->state; int fd = my_data->fd; int id = my_data->id; int id1 = my_data->id1; int A = my_data->A; conns[id1].A=10; printf("\n\tThread Created.\ns: %d \tID: %d\t FD: %d \tBuf: %s",state,id1,fd,buffer); int len=strlen(buffer); char strng[]="From Thread: "; strcat(strng,buffer); conns[id1].state=state; conns[id1].fd=fd; conns[id1].id2=3; conns[id1].buf= strng; printf("\nChanged Buffer: %s",strng); // Writing Process Via Thread if(conns[id1].state == 2 && FD_ISSET(conns[id1].fd, &wr)) //CST_WRITE { if(write(conns[id1].fd,strng, strlen(strng)) <= 0) close_and_free(id1); printf("\n [%d] Thread Sent: %s", id1, strng); time(&t); fprintf(log,"\n [%d] Thread Sent: %s.\nTime = %s\n", id1, strng,ctime(&t)); conns[id1].state = 1; //CST_READ } liveThread--; printf("LiveThread:%d\tThread Exits........................................................",liveThread); fflush(stdout); pthread_exit(NULL); }
int main() { printf("\nAssign Threshold Connections : "); scanf("%d",&MaxPendingConnection); do{ printf("\nAssign Threshold Thread Pool Size : "); scanf("%d",&MaxThreadPool); }while(MaxThreadPool>=MaxPendingConnection); pthread_t threads[MaxPendingConnection]; //CREATING MEMORY AREA FOR ALL THREADS threadArray = (connections *) malloc( sizeof(connections) * MaxThreadPool ); if(threadArray == (connections *) 0) { printf("Can't allocate memory for Threads table"); exit(1); } //Creating Log File.... log = fopen("Log_serverWithoutLiveThreadPool.txt","w"); fprintf(log,"MaxConnection: %d\nMaxLiveThreadPool: %d\n\n",MaxPendingConnection,MaxThreadPool); // ASSIGNING SERVER PORT ADDRESS printf("\nAssign the Server Port: "); scanf("%u",&echoServerPort); // CREATING SOCKET FOR INCOMMING CONNECTION serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (serverSocket<0) Error(1); //Setting SO_REUSEADDR on Main Socket.. if(setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (void *) &set, sizeof(set)) < 0) { printf("Can't set SO_REUSEADDR on main socket"); exit(1); } // CREATING LOCAL ADDRESS STRUCTURE memset( &echoServerAddress, 0, sizeof(echoServerAddress)); echoServerAddress.sin_family = AF_INET; echoServerAddress.sin_addr.s_addr = htonl(INADDR_ANY); echoServerAddress.sin_port = htons(echoServerPort); // BINDING ADDRESS Binder = bind( serverSocket, (struct sockaddr *) &echoServerAddress, sizeof(echoServerAddress) ); if(Binder<0) Error(2); // Checking for incomming Connection waiting Listen=listen(serverSocket,MaxPendingConnection); if(Listen<0) Error(3); //CREATING MEMORY AREA FOR ALL CONNECTION conns = (connections *) malloc( sizeof(connections) * MaxPendingConnection ); if(conns == (connections *) 0) { printf("Can't allocate memory for connections table"); exit(1); } for(connID=0;connID<MaxPendingConnection;connID++) conns[connID].state = 0;//CST_FREE // Accepting connections printf("\nSERVER STARTED...\n"); time(&t); fprintf(log,"\nSERVER STARTED..\nTime = %s",ctime(&t)); while(!flagStop) { /* set FDs for select() */ FD_ZERO(&rd); FD_ZERO(&wr); n = 0; FD_SET(serverSocket, &rd); n = MAX(serverSocket, n); /* set FDs for the connections */ for(connID=0; connID<MaxPendingConnection; connID++) { if(conns[connID].state == 1) //CST_READ { FD_SET(conns[connID].fd, &rd); n = MAX(n, conns[connID].fd); conns[connID].id2=0; } else if(conns[connID].state == 2) //CST_WRITE { FD_SET(conns[connID].fd, &wr); n = MAX(n, conns[connID].fd); } } // Selecting the Socket for Read n = select(n + 1, &rd, &wr, (fd_set *) NULL, (struct timeval *) 0); if(n < 0) { printf("select() failed..."); exit(1); } if(n == 0) continue; /* Something happend, handle it..) */ if(FD_ISSET(serverSocket, &rd)) { /* get free slot, if one */ newid = -1; for(connID=0; connID<MaxPendingConnection; connID++) { if(conns[connID].state == 0) //CST_FREE { newid = connID; break; } } if((newid ==-1 || newid>MaxPendingConnection-1)&& warnFlag==1 ) { warnFlag = 2; printf("\n WARNING: Too many connections\n"); } else if(newid !=-1) { // Accept the connection... clientLength=sizeof(echoClientAddress); memset(&echoClientAddress, 0, clientLength); // Accepting the Connection from Client clientSocket = accept(serverSocket, (struct sockaddr *) &echoClientAddress, &clientLength); if(clientLength<0) Error(4); printf("\n Talking with client having IP Address : %s\n" , inet_ntoa(echoClientAddress.sin_addr)); printf(" [%d] We have a connection!!\n", newid); conns[newid].state = 1; //CST_READ if((conns[newid].buf = (char *)malloc(BufferSize)) < 0) { printf("\nCan't allocate memory"); exit(1); } sprintf(conns[newid].buf, "Recieved Acknowledgement.\n"); conns[newid].fd = clientSocket; } } // Checking Active Sockets for(connID=0;connID<MaxPendingConnection;connID++) { // we can read if(conns[connID].state == 1 && FD_ISSET(conns[connID].fd, &rd)) //CST_READ { memset((void *) conns[connID].buf, 0, BufferSize); if(read(conns[connID].fd, conns[connID].buf, BufferSize) <= 0) close_and_free(connID); printf("\n\n\n\n ConnID: [%d] Got: %s", connID, conns[connID].buf); time(&t); fprintf(log,"\n\n ConnID: [%d] Got: %s.\nTime = %s", connID, conns[connID].buf,ctime(&t)); conns[connID].state = 2; //CST_WRITE // For EXITing the connection. if(strstr(conns[connID].buf, "exit()") == conns[connID].buf) { printf("\n [%d] Closing connection\n", connID); close_and_free(connID); } else if(strstr(conns[connID].buf, "die()") == conns[connID].buf) { printf("\nGot die() from connection #%d, dying!\n", connID); flagStop = 1; break; } // Thread Computing...based on the concept of creating new thread per request... conns[connID].id1=connID; q.push(conns[connID]); if(used>=MaxThreadPool) { if(liveThread==0) used=0; } if(used<MaxThreadPool) { threadArray[used]=q.front(); pt = pthread_create(&threads[used], NULL, computing, (void *)&threadArray[used]); liveThread++ ; used++ ; if (pt) { printf("ERROR; return code from pthread_create() is %d for Connection ID: %d\n", pt, connID); liveThread--; } printf("\nLiveThread: %d\tTotal Connections: %d\tUsed: %d",liveThread,newid+1,used); q.pop(); } } } } /* close all connections before dying */ for(connID=0;connID<MaxPendingConnection;connID++) if(conns[connID].state != CST_FREE) { close_and_free(connID); } close(serverSocket); fclose(log); pthread_exit(NULL); free(threadArray); free(conns); return 0; }
void send_cb(EV_P_ ev_io *watcher, int revents) { if(EV_ERROR & revents) { printf("error event in read"); return; } struct conn_ctx *conn_ctx = (struct conn_ctx *)watcher; struct conn *conn = conn_ctx->conn; struct conn *another = conn->another; char **buf = &conn->buf; if(another == NULL) { close_and_free(EV_A_ conn); return ; } if(conn->type == 1 && conn->connected == 0) { struct sockaddr_storage addr; socklen_t len = sizeof addr; int r = getpeername(conn->fd, (struct sockaddr*)&addr, &len); if(r == 0) { conn->connected = 1; ev_io_stop(EV_A_ &conn->send_ctx->io); ev_timer_stop(EV_A_ &conn->send_ctx->watcher); ev_io_start(EV_A_ &conn->recv_ctx->io); ev_io_start(EV_A_ &another->recv_ctx->io); } else { if(debug) printf("error getpeername\n"); close_and_free(EV_A_ another); close_and_free(EV_A_ conn); } return ; } if(conn->buf_len == 0) { close_and_free(EV_A_ conn->another); close_and_free(EV_A_ conn); return ; } else { ssize_t s = send(conn->fd, *buf + conn->buf_idx, conn->buf_len, 0); if(s < 0) { if(errno != EAGAIN && errno != EWOULDBLOCK) { close_and_free(EV_A_ conn->another); close_and_free(EV_A_ conn); } return ; } else if( s < conn->buf_len ) { conn->buf_len -= s; conn->buf_idx += s; } else { //send all conn->buf_len = 0; conn->buf_idx = 0; ev_io_stop(EV_A_ &conn->send_ctx->io); if(another != NULL) { ev_io_start(EV_A_ &another->recv_ctx->io); } else { close_and_free(EV_A_ another); close_and_free(EV_A_ conn); } } } }
void recv_cb(EV_P_ ev_io *watcher, int revents) { if(EV_ERROR & revents) { printf("error event in read"); return; } struct conn_ctx *conn_ctx = (struct conn_ctx *)watcher; struct conn *conn = conn_ctx->conn; struct conn *another = conn->another; char **buf = &another->buf; if(conn->type == 0) { ev_timer_again(EV_A_ &conn->recv_ctx->watcher); } else { ev_timer_again(EV_A_ &another->recv_ctx->watcher); } ssize_t r = recv(conn->fd, *buf, BUFSIZE, 0); if(debug) printf("fd %d --------> recv %d\n", conn->fd, r); if(r == 0) { close_and_free(EV_A_ conn->another); close_and_free(EV_A_ conn); return ; } else if (r < 0) { if(errno == EAGAIN || errno == EWOULDBLOCK) { return ; } else { close_and_free(EV_A_ conn->another); close_and_free(EV_A_ conn); return ; } } RC4(&conn->key, r, *buf, *buf); int s = send(another->fd, *buf, r, 0); if(debug) printf("send to fd %d --------> %d\n", another->fd, s); if(s == -1) { if(errno == EAGAIN || errno == EWOULDBLOCK) { another->buf_len = r; another->buf_idx = 0; ev_io_stop(EV_A_ &conn->recv_ctx->io); ev_io_start(EV_A_ &another->send_ctx->io); } else { close_and_free(EV_A_ conn->another); close_and_free(EV_A_ conn); } return ; } else if(s < r) { another->buf_len = r-s; another->buf_idx = s; ev_io_stop(EV_A_ &conn->recv_ctx->io); ev_io_start(EV_A_ &another->send_ctx->io); } return ; }