bool ttMorse::msend( ) { return mmsend( ); }
bool ttMorse::msend( char *str ) { mstr = str; return mmsend( ); }
int main(){ int newfd; struct sockaddr_storage remoteaddr; socklen_t addrlen; char buf[800]; int nbytes; char remoteIP[INET6_ADDRSTRLEN]; int yes = 1; int i, j; struct addrinfo hints, *ai, *ai_itr; FD_ZERO(&master); FD_ZERO(&read_fds); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int rv; if (rv = getaddrinfo(NULL, PORT, &hints, &ai)){ fprintf(stderr, "server: %s\n", gai_strerror(rv)); exit(1); } for(ai_itr = ai; ai_itr!=NULL; ai_itr = ai_itr->ai_next) { listener = socket(ai_itr->ai_family, ai_itr->ai_socktype, ai_itr->ai_protocol); if(listener < 0) { continue; } setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if (bind(listener, ai_itr->ai_addr, ai_itr->ai_addrlen) <0 ){ close(listener); continue; } break; } if (ai_itr == NULL) { fprintf(stderr, "server: failed to bind\n"); exit(2); } freeaddrinfo(ai); if (listen(listener, 10) == -1) { perror("listen"); exit(3); } FD_SET(listener, &master); fdmax = max(fdmax, listener); sigset_t mask; sigset_t orig_mask; struct sigaction act; memset(&act, 0, sizeof act); act.sa_handler = sigint_handler; sigaction(SIGINT, &act, 0); sigemptyset(&mask); sigaddset(&mask, SIGINT); sigprocmask(SIG_BLOCK, &mask, &orig_mask); while(1){ read_fds = master; int res; if ( (res=pselect(fdmax+1, &read_fds, NULL, NULL, NULL,&orig_mask)) == -1) { if(errno!=EINTR){ perror("select"); exit(4);} } else if(!res){ printf("Res == 0\n"); } if(got_int){ bool hasconnected = false; do{ printf("Cleaning up\n"); hasconnected = false; for(i = 0; i<=fdmax; i++){ if(FD_ISSET(i, &read_fds) && i!=listener && ol_list[i]){ char b[200] = {}; mmsend(i, "[SHUTDOWN]\n"); int x = recv(i, b, sizeof b, 0); if(x>0){ mmsend(i, "[SHUTDOWN]\n"); } if(!x){ printf("%d %s closed.\n", i, user_list[i]); user_list[i][0] = 0; ol_list[i] = 0; ip_list[i][0] = 0; } hasconnected = true; } } } while(hasconnected); printf("Closed all\n"); return 0; } for(i = 0; i<=fdmax; i++) { if (FD_ISSET(i, &read_fds)) { if (i == listener) { // new connection if(got_int) continue; addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); if(newfd == -1 && !got_int) { if(errno != EINTR) perror("accept"); } else { FD_SET(newfd, &master); fdmax = max(fdmax, newfd); printf("server: %s connected on socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr *)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); strcpy(ip_list[newfd], remoteIP); user_list[newfd][0] = 0; ol_list[newfd] = 0; } } else { // handle data from client if ( (nbytes = recv(i, buf, sizeof buf, 0)) <= 0 ) { if (nbytes == 0 ){ // connection closed printf("server: (%s) on socket %d hung up\n", ip_list[i], i); close(i); ip_list[i][0] = 0; user_list[i][0] = 0; ol_list[i] = 0; FD_CLR(i, &master); // broadcast here } else { if(errno!=EINTR) perror("recv"); } } else { // broadcast here char ret[800]; currfd = i; int bm = handle_data(buf, ret); if(bm == BROADCAST_SELF){ msend(i, ret, strlen(ret), 0); } else if(bm == BROADCAST_OTHERS){ broadcastOthers(ret, i); } else if(bm == BROADCAST_ALL){ broadcastAll(ret); } else { broadcastOne(ret); } } } // END handle data from client } } // END for loop iteration through file descriptors } // END while loop return 0; }