#include #include #include #include #include #include #include #include #define PORT 7989 // port we're listening on #define SHOW 1 // command show #define MESSAGE 2 #define HELP 3 #define NICK 4 #define NEWLINE 5 void write_to_socket(int target,char *buff_to_send,int len); int check_for_command(char *buffer,int *p); int is_fd_valid(int destination) ; void type_writer(char *buf,int len,int fd); typedef struct { int id; /* socket descripter */ char nick[30]; /* store the nick here */ short flag_nick; }USER; USER user[20]; int usercount=0; int main(void) { fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() struct sockaddr_in myaddr; // server address struct sockaddr_in remoteaddr; // client address int fdmax; // maximum file descriptor number int listener; // listening socket descriptor int newfd; // newly accept()ed socket descriptor char buf[1024]; // buffer for client data int nbytes; int yes=1; // for setsockopt() SO_REUSEADDR, below int addrlen; int i, j,k,tmp,destination=0; int str_len; char c; char *tmp_ptr; //USER user[20]; //int usercount=0; bzero(user,sizeof(USER)); FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); // get the listener if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } // lose the pesky "address already in use" error message if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } // bind myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = INADDR_ANY; myaddr.sin_port = htons(PORT); memset(&(myaddr.sin_zero), '\0', 8); if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) { perror("bind"); exit(1); } // listen if (listen(listener, 10) == -1) { perror("listen"); exit(1); } // add the listener to the master set FD_SET(listener, &master); // keep track of the biggest file descriptor fdmax = listener; // so far, it's this one // main loop for(;;) { read_fds = master; // copy it if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(1); } // run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listener) { // handle new connections addrlen = sizeof(remoteaddr); if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) { perror("accept"); } else { FD_SET(newfd, &master); // add to master set if (newfd > fdmax) { // keep track of the maximum fdmax = newfd; } user[usercount].id=newfd; ++usercount; printf("selectserver: new connection from %s on " "socket %d\n", inet_ntoa(remoteaddr.sin_addr), newfd); bzero(buf,sizeof(buf)); strcpy(buf,"\n\n\n\n\n\n\n\n\n\n\n********************************************************************************\n"); str_len=strlen(buf); write_to_socket(newfd,buf,str_len); bzero(buf,sizeof(buf)); strcpy(buf,"\n\n\t\t\tWelcome to AnKiChaTTEr chat server\n\n\n"); str_len=strlen(buf); type_writer(buf,str_len,newfd); bzero(buf,sizeof(buf)); strcpy(buf,"********************************************************************************\n\n" "\t\t\t~Type /SHOW/ to list all online users\n\n" "\t~ To send a message to everyone in the room just type the message and press enter\n\n" "\t\t~ Type /numeric-user/ to send a message to particular user only\n\n" "\t\t ex: /6/ Hi number 6 how r u\n\n" "\t\t\t~ Type /HELP/ to see server commands\n\n\n" "********************************************************************************\n\n\n\n>>" ); str_len=strlen(buf); write_to_socket(newfd,buf,str_len); //strcpy(buff,"\tWelecome to Ank's chat server\n"); } } else { // handle data from a client if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed printf("selectserver: socket %d hung up\n", i); } else { perror("recv"); } close(i); // bye! FD_CLR(i, &master); // remove from master set } else { // we got some data from a client //printf("\n%s\n",buf); for(j = 0; j <= fdmax; j++) { // send to everyone! if (FD_ISSET(j, &master)) { // except the listener and ourselves if (j != listener && j != i) { switch(check_for_command(buf,&destination)) { case SHOW: //strcpy(buf,"Got the command request :-)\n>>\r\n" ); //str_len=strlen(buf); k= usercount-1; bzero(buf,sizeof(buf)); while(k>=0) { sprintf(buf,"<%d>\n>>",user[k].id); str_len=strlen(buf); write_to_socket(i,buf,str_len); --k; } j=1111; // to end the loop break; case MESSAGE: if( is_fd_valid(destination) ) { tmp_ptr=buf; while(*tmp_ptr==' ') ++tmp_ptr; c=destination; *(tmp_ptr+1)=i+'0';//(char)destination; tmp_ptr=strchr(buf,'\n'); //str_len=strlen(buf); write_to_socket(destination,buf,tmp_ptr-buf+1); printf("\nGood show\n"); } else { bzero(buf,sizeof(buf)); strcpy(buf,"Invalid user\n>>\r\n"); str_len=strlen(buf); write_to_socket(i,buf,str_len); } j=1111; // to end the loop break; case HELP: bzero(buf,sizeof(buf)); strcpy(buf,"\n\n\n********************************************************************************\n\n\n" "\t\t\t~Type /SHOW/ to list all online users\n\n" "\t~ To send a message to everyone in the room \n" "\t\t\tjust type the message and press enter\n\n" "\t\t~ Type /numeric-user/ to send a message to particular user only\n\n" "\t\t\t\t ex: /6/ Hi number 6 how r u\n\n" "\t\t\t~ Type /HELP/ to see server commands\n\n\n>>" "********************************************************************************\n\n\n\n>>" ); str_len=strlen(buf); write_to_socket(newfd,buf,str_len); j=1111; break; case NEWLINE: bzero(buf,sizeof(buf)); sprintf(buf,">>"); //str_len=strlen(buf); write_to_socket(i,buf,strlen(buf)); j=1111; break; case NICK: //printf("Got the nick\n"); //bzero(buf,sizeof(buf)); tmp_ptr=buf; tmp_ptr+=6; for(tmp=0;tmp