/** @fn bool line_socket::Send(SOCKET_PACKAGE_SENT_PTR pack, int pack_num) @detail 该函数将数据投递到发送队列中 @param[in] pack 发送数据包数组 @param[in] pack_num 数据包数组大小 @return 如果发送成功将返回true, 否则将返回false @note */ bool line_socket::Send(SOCKET_PACKAGE_SENT_PTR pack, int pack_num) { bool is_ok = true; wait_sending_pack_queue_lock_.Lock(); for(int i = 0; i < pack_num; ++i) if((pack + i) != NULL) { send_private(pack + i); } wait_sending_pack_queue_lock_.Unlock(); return is_ok; }
void getnick(int fd, char* nm) { char enterNick[] = "Enter a nick (Max 1023 characters) : "; int inbytes, len; char clnick[1024]; send_private(fd, enterNick); if((inbytes = recv(fd, clnick, 1023, 0)) == -1) { perror("server: read error -- nick"); close(fd); } if(inbytes==0) { close(fd); printf("Client on socket %d closed connection before entering nick\n", fd); } for(int i=0; i<inbytes-1; ++i) { *(nm+i) = clnick[i]; } *(nm+inbytes-1) = '\0'; }
void multiplexer(int listener) { fd_set readfds, masterfd; FD_ZERO(&readfds); FD_ZERO(&masterfd); FD_SET(listener, &masterfd); FD_SET(STDIN, &masterfd); int fdmax; socklen_t addrsize; struct sockaddr_storage their_addr; int inbytes, new_fd, var; char outmsg[1024], inmsg[1024]; char incoming_IP[INET6_ADDRSTRLEN]; //Extra size doesn't hurt fdmax = listener; while(1) { readfds = masterfd; if (select(fdmax+1, &readfds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } for(int i=0; i<=fdmax; i++) { if(FD_ISSET(i, &readfds)) { if(i==listener) { addrsize = sizeof their_addr; if((new_fd = accept(listener, (struct sockaddr *)&their_addr, &addrsize)) == -1) { perror("server: accept error"); } else { char c[1024]; FD_SET(new_fd, &masterfd); // add to master set if (new_fd > fdmax) fdmax = new_fd; inet_ntop(their_addr.ss_family, get_in_addr(&their_addr), incoming_IP, INET6_ADDRSTRLEN); printf("Server received a connection from %s on socket %d\n",incoming_IP, new_fd); getnick(new_fd, c); client_t *cli = (client_t *)malloc(sizeof(client_t)); cli->connfd = new_fd; cli->uid = uid++; sprintf(cli->name, "%s", c); /* Add client to the queue */ queue_add(cli); var = get_index(new_fd); sprintf(outmsg, "%s %s %s", "||| WELCOME",clients[var]->name, "|||\n"); send_private(new_fd, outmsg); sprintf(outmsg, "%s joined the room\n",clients[var]->name); printf("%s", outmsg); //display on server broadcast_msg(new_fd, outmsg, &masterfd, fdmax, listener); } } else if(i == 0) { if(fgets(outmsg, 1023, stdin)==NULL) return ; else { char out[1024]; sprintf(out, "%s %s","[Server] : ", outmsg); broadcast_msg(i, out, &masterfd, fdmax, listener); } } else //Only case left is that a client got some data { var = get_index(i); if(readmsg(i, 1023, inmsg)) { printf("[%s] : %s", clients[var]->name, inmsg); //display on server sprintf(outmsg, "[%s] : %s",clients[var]->name, inmsg); broadcast_msg(i, outmsg, &masterfd, fdmax, listener); } else { printf("%s left the room\n", clients[var]->name); //display on server sprintf(outmsg, "%s %s",clients[var]->name, "left the room\n"); broadcast_msg(i, outmsg, &masterfd, fdmax, listener); FD_CLR(i, &masterfd); close(i); queue_delete(i); } } } } } }
void sigusr2 ( int sno ) { printf ( "SIGUSR2 caught\n") ; send_private ( sno ) ; siglongjmp ( s_env, 0 ) ; }