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

arrow
arrow
    全站熱搜

    = = 發表在 痞客邦 留言(0) 人氣()