客户端服务器应用程序

时间:2017-07-27 08:25:56

标签: c select client-server

我正在开发一个客户端/服务器c项目,我有一个服务器和多个客户端向它发送请求。应用程序使用套接字进行通信(AF_UNIX),整个连接部分很好(比如说,使用其他方法而不是select(),一切都可以正常工作)。 但是,我愿意使用select()来通知服务器集合中文件描述符的新事件,即服务器套接字fd和单个客户端。

我已经清除了与我面临的问题无关的部分的代码,现在我只有以下内容:

  • 服务器,初始化套接字通信并创建一个必须执行select()和accept()函数的线程:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <pthread.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <sys/un.h>
    #include <sys/socket.h>
    #include <sys/select.h>
    #include <string.h>
    #include <utility.h>
    
    void* handConn(void* address){
        int fd_cli;
    
        while(1){
    
            printf("HANDLER:    in handler\n");
            if (select(max_fd+1, &rdset,NULL, NULL,NULL) == -1) {
                perror("select");
                exit(EXIT_FAILURE);
            }
    
            for(int i=0; i<=max_fd; i++){
                if(FD_ISSET(i,&rdset) && i==sfd){
                    printf("new incoming connection to accept\n");
                    fd_cli=accept(sfd,NULL,NULL);
                    FD_SET(fd_cli,&rdset);
                    if(fd_cli>max_fd) max_fd=fd_cli;
                }
                else if(FD_ISSET(i,&rdset) && i!=sfd){
                    printf("event on old connection\n");
                }
            }
            FD_ZERO(&rdset);
        }
    
        return (void*) NULL;
    }
    
    int main(void){
        int i, fd_cli, tid;
        max_fd=0;
    
        struct sockaddr_un sa;
        sa.sun_family=AF_UNIX;
        strncpy(sa.sun_path,"tmp/sock", sizeof(sa.sun_path));
    
        if((sfd=socket(AF_UNIX,SOCK_STREAM,0))<0){ 
            perror("Server socket");
            exit(EXIT_FAILURE);
        }
    
        if ( bind(sfd,(struct sockaddr *)&sa, sizeof(sa))<0){
            perror("bind");
            exit(EXIT_FAILURE);
        }
    
        listen(sfd,10); //10 is just for example purpose only
    
        /* Init fd_set */
    
        FD_ZERO(&rdset);
        FD_SET(sfd, &rdset);
        max_fd=sfd;
    
        /*Handler thread creation */
    
        if( pthread_create(&tid, NULL, handConn, (void*) &sa)<0){
             perror("Handler thread creation");
             exit(EXIT_FAILURE);
        }
    
    
        pthread_join(tid, NULL);
        return 0;
    }
    
  • 客户端执行以下操作(我从代码中删除了write-bytes控件,因为在这种情况下它不相关):

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <errno.h>
    #include <utility.h>
    
    
    int main(){
    
        int fd_cli;
    
        struct sockaddr_un sa;
        sa.sun_family=AF_UNIX;
        strncpy(sa.sun_path,"tmp/sock", sizeof(sa.sun_path));
    
        if( (fd_cli = socket(AF_UNIX, SOCK_STREAM, 0))==-1){
            perror("Client socket connection");
            return -1;
        }
    
        while( (connect(fd_cli,(struct sockaddr*)&sa, sizeof(struct sockaddr_un))) == -1 ) {
            if ( errno == ENOENT ) { sleep(1); }
            else{
                perror("Connect");
                exit(EXIT_FAILURE);
            }
         }
    
         printf("connected to server\n");
    
         /*write something to server*/
    
         int retvalue = write(sfd, writePointer, bytesLeft);
         if(retvalue=0) /*handle...*/
         if(retvalue==-1){
              perror("writing");
              return -1;
          }
    
         close(fd_cli);
    
         return 0;
    
     }
    
    • 最后,其中的库定义了上述代码中使用的变量:

      #ifndef utility_h
      #define utility_h
      
      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/select.h>
      
      fd_set reset;
      
      int sfd; //server fd
      int max_fd;
      

我面临的问题是,即使只执行一个客户端,select也看不到传入的连接。 我期望的是处理程序打印以下内容:

new incoming connection to accept
event on old connection

第一个在接受之前,第二个在它截取写入之前。 该程序,因为它不打印那些,所以处理程序甚至不能拦截新的传入连接。 它只会卡在select()上。

问题可能是什么?

0 个答案:

没有答案