close
client result socketfd 4
XXXXX:~/socket/select/test1_add_strtok$ ./client input message to server or client : ex: to clientid message recv message : online client id 4 recv message : welcome to myserver,your client id is 4 to 4 aaaa input message to server or client : ex: to clientid message recv message : aaaa From client 4 message recv message : to 4 aaaa recv message : online client id 4 5 recv message : abc From client 5 message |
client result sockfd 5
xxxx:~/socket/select/test1_add_strtok$ ./client input message to server or client : ex: to clientid message recv message : online client id 4 5 recv message : welcome to myserver,your client id is 5 to 4 abc input message to server or client : ex: to clientid message recv message : to 4 abc |
server result
steven@73-247:~/socket/select$ ./server Waiting on select()... Listening client socket 3 is readable New incoming connection - 4 Waiting on select()... Descriptor 4 is readable server recv: to 4 aaaa Waiting on select()... Listening client socket 3 is readable New incoming connection - 5 Waiting on select()... Descriptor 5 is readable server recv: to 4 abc Waiting on select()... |
server code
steven@73-247:~/socket/select$ cat server.c #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <errno.h> #include <string.h> #define SERVER_PORT 1234 #define TRUE 1 #define FALSE 0 void int2str(int i, char *s) { sprintf(s,"%d",i); } main (int argc, char *argv[]) { int i, len, rc, on = 1,m; int listen_sd, max_sd, new_sd; int tok_i; int desc_ready, end_server = FALSE; int close_conn; char buffer[80],temp_buffer[80],s[80]; struct sockaddr_in addr; struct timeval timeout; fd_set master_set,working_set; char clist[80]; int loop = 4,loop_i = 4; char *tok; char to_mes[80]; int count=0,to=0,to_cid; /*************************************************************/ /* Create an AF_INET stream socket /*************************************************************/ listen_sd = socket(PF_INET, SOCK_STREAM, 0); if (listen_sd < 0) { perror("socket() failed"); exit(-1); } /*************************************************************/ /* Allow socket descriptor to be reuseable */ /*On success, zero is returned. On error, -1 is returned */ /*************************************************************/ rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR,(char *)&on, sizeof(on)); if (rc < 0) { perror("setsockopt() failed"); close(listen_sd); exit(-1); } /*************************************************************/ /* Set socket to be non-blocking. All of the sockets for */ /* the incoming connections will also be non-blocking since */ /* they will inherit that state from the listening socket. */ /*on success zero is returned. On error, -1 is returned */ /*int ioctl(int fd, unsigned long request, char *arg) */ /*FLOCLEX : set the close-on-exec flag for file descriptor */ /*FIONCLEX : clear the close-on-exec flag for file descriptor*/ /*FIOASYNC : allows the receipt of asynchronous I/O signals */ /*FIONBIO : File IOctl Nonblock I/O */ /*************************************************************/ rc = ioctl(listen_sd, FIONBIO, (char *)&on); if (rc < 0) { perror("ioctl() failed"); close(listen_sd); exit(-1); } /*************************************************************/ /* Bind the socket */ /*************************************************************/ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(SERVER_PORT); rc = bind(listen_sd,(struct sockaddr *)&addr, sizeof(addr)); if (rc < 0) { perror("bind() failed"); close(listen_sd); exit(-1); } /*************************************************************/ /* Set the listen back log */ /*************************************************************/ rc = listen(listen_sd, 32); if (rc < 0) { perror("listen() failed"); close(listen_sd); exit(-1); } /*************************************************************/ /* Initialize the master fd_set */ /*************************************************************/ FD_ZERO(&master_set); max_sd = listen_sd; /*************************************************************/ /* Initialize the timeval struct to 3 minutes. If no */ /* activity after 3 minutes this program will end. */ /*************************************************************/ /*************************************************************/ /* Loop waiting for incoming connects or for incoming data */ /* on any of the connected sockets. */ /*************************************************************/ do{ //FD_ZERO(&master_set); FD_SET(listen_sd,&master_set); timeout.tv_sec = 5 * 60; timeout.tv_usec = 0; /**********************************************************/ /* Copy the master fd_set over to the working fd_set. */ /**********************************************************/ memcpy(&working_set, &master_set, sizeof(master_set)); /**********************************************************/ /* Call select() and wait 5 minutes for it to complete. */ /* success number of file descriptors */ /* error -1 */ /*int select(int nfds, fd_set *readfds, fd_set *writefds, */ /* fd_set *exceptfds, struct timeval *timeout);*/ /**********************************************************/ printf("Waiting on select()...\n"); rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout); //printf("rc %d\n",rc); /**********************************************************/ /* Check to see if the select call failed. */ /**********************************************************/ if (rc < 0) { perror(" select() failed"); break; } /**********************************************************/ /* Check to see if the 5 minute time out expired. */ /**********************************************************/ if (rc == 0) { printf(" select() timed out. End program.\n"); break; } /**********************************************************/ /* One or more descriptors are readable. Need to */ /* determine which ones they are. */ /**********************************************************/ desc_ready = rc; for (i=0; i <= max_sd && desc_ready > 0; ++i) { /*******************************************************/ /* Check to see if this descriptor is ready */ /*int FD_ISSET(int fd, fd_set *set); */ /*******************************************************/ if (FD_ISSET(i, &working_set)){ /****************************************************/ /* A descriptor was found that was readable */ /****************************************************/ desc_ready -= 1; /****************************************************/ /* Check to see if this is the listening socket */ /****************************************************/ if (i == listen_sd){ printf(" Listening client socket %d is readable\n",i); /*************************************************/ /* Accept all incoming connections */ /*************************************************/ /**********************************************/ /* Accept each incoming connection. */ /* Success non-negative integer */ /* error -1 */ /**********************************************/ struct sockaddr_in client_addr; int addrlen = sizeof(client_addr); new_sd = accept(listen_sd, (struct sockaddr*)&client_addr,&addrlen); if (new_sd < 0) { if (errno != EWOULDBLOCK) { perror(" accept() failed"); end_server = TRUE; } break; } /**********************************************/ /* Add the new incoming connection */ /**********************************************/ printf(" New incoming connection - %d\n", new_sd); memset(clist,0,strlen(clist)); strcpy(clist,"online client id "); for(loop = 4;loop < max_sd+2; loop++){ //send(loop,clist,strlen(clist),0); int2str(loop,s); strcat(clist,s); strcat(clist," "); } clist[strlen(clist)]='\0'; //debug //printf(" total clist %s\n",clist); for(loop_i=4;loop_i < max_sd+2;loop_i++){ if(send (loop_i,clist,80,0) < 0){ printf("send error"); close_conn = TRUE; } } memset(clist,0,strlen(clist)); strcpy(clist,"welcome to myserver,your client id is "); int2str(new_sd,s); strcat(clist,s); if(send(new_sd,clist,80,0)<0){ printf("send error"); close_conn = TRUE; } FD_SET(new_sd, &master_set); if (new_sd > max_sd){ max_sd = new_sd; } } /****************************************************/ /* existing connection must be readable */ /* Receive all incoming data on this socket */ /****************************************************/ else{ memset(buffer,0,strlen(buffer)); memset(to_mes,0,strlen(to_mes)); printf(" Descriptor %d is readable\n", i); close_conn = FALSE; /**********************************************/ /* Receive data on this connection until the */ /* recv fails with EWOULDBLOCK. */ /**********************************************/ rc = recv(i, buffer, sizeof(buffer), 0); if (rc < 0){ if (errno != EWOULDBLOCK){ perror(" recv() failed"); close_conn = TRUE; } } buffer[strlen(buffer)-1]='\0'; strcpy(temp_buffer,buffer); tok=strtok(temp_buffer," "); while(tok!=NULL){ if( !strcmp(tok,"to") && count==0){ to=1; } if(to==1 && count==1){ to_cid=atoi(tok); } if(to==1 && count>1){ strcat(to_mes,tok); strcat(to_mes," "); } tok=strtok(NULL," "); count++; } strcpy(temp_buffer,to_mes); strcat(temp_buffer," From client "); int2str(i,s); strcat(temp_buffer,s); strcat(temp_buffer," message "); temp_buffer[strlen(temp_buffer)-1]='\0'; if(to==1){ if(send(to_cid,temp_buffer,80,0)<0){ printf("send error"); close_conn = TRUE; } } to=0; count=0; if (rc == 0){ printf(" Connection closed\n"); close_conn = TRUE; } /**********************************************/ /* Data was recevied */ /**********************************************/ len = rc; printf(" server recv: %s\n",buffer); //printf(" %d bytes received\n", len); /**********************************************/ /* Echo the data back to the client */ /**********************************************/ rc = send(i, buffer, len, 0); if (rc < 0){ perror(" send() failed"); close_conn = TRUE; } if (close_conn){ close(i); FD_CLR(i, &master_set); if (i == max_sd){ while (FD_ISSET(max_sd, &master_set) == FALSE){ max_sd -= 1; } } } } /* End of existing connection is readable */ } /* End of if (FD_ISSET(i, &working_set)) */ } /* End of loop through selectable descriptors */ } while (end_server == FALSE); /*************************************************************/ /* Cleanup all of the sockets that are open */ /*************************************************************/ for (i=0; i <= max_sd; ++i) { if (FD_ISSET(i, &master_set)) close(i); } } |
client code
steven@73-245:~/socket/select/test1_add_strtok$ cat client.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <pthread.h> #include <unistd.h> void* recv_pthread(void* argument); void* send_pthread(void* argument); void error(char *msg) { perror(msg); exit(0); } int sockfd; int main(int argc, char *argv[]) { int portno,m,on=1; struct sockaddr_in serv_addr; struct hostent *server; char buffer[80],buff[80]; char* host_name = "192.168.73.247"; sockfd = socket(PF_INET, SOCK_STREAM,0); if (sockfd < 0){ error("ERROR opening socket"); } m=setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,(char *)&on, sizeof(on)); if (m < 0){ perror("setsockopt() failed"); close(sockfd); exit(-1); } bzero((char *) &serv_addr,sizeof(serv_addr)); serv_addr.sin_family = PF_INET; serv_addr.sin_port = htons(1234); serv_addr.sin_addr.s_addr = inet_addr(host_name); if (connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) <0){ error("ERROR connecting"); } pthread_t recv_id; pthread_t send_id; if(pthread_create(&recv_id,NULL,recv_pthread,NULL)!=0){ printf("error creating the recv_thread\n"); } if(pthread_create(&send_id,NULL,send_pthread,NULL)!=0){ printf("error creating the send_thread\n"); } while(1){ sleep(1); } return 0; } void* recv_pthread(void* argument){ int n; char buff[80]; while(1){ memset(buff,0,strlen(buff)); n=recv(sockfd,buff,80,0); buff[strlen(buff)] = '\0'; if (n < 0){ error("ERROR reading from socket"); } printf("recv message : %s\n",buff); } } void* send_pthread(void* argument){ int n; char buffer[80]; while(1){ memset(buffer,0,strlen(buffer)); printf("\ninput message to server or client : ex: to clientid message\n"); fgets(buffer,80,stdin); n = send(sockfd,buffer,strlen(buffer),0); if (n < 0){ error("ERROR writing to socket"); } } } steven@73-245:~/socket/select/test1_add_strtok$ |
makefile
all:client server client:client.o cc -o client client.o -lpthread server:server.o cc -o server server.o client.o:client.c cc -c client.c server.o:server.c cc -c server.c clean: rm -rf *.o client server |
全站熱搜