2015-09-23 183 views
2

我有一个侦听两个不同端口的TCP服务器。我在端口8888上创建了两个不同的套接字,并在端口6634上创建了一个。我在这些端口上侦听,然后在FD_SET中添加两个套接字并将它们传递给select()函数... 当套接字准备好读取时,用FD_ISSET查看我有哪些端口有消息要读取。侦听两个不同端口的TCP服务器

任何方式,当我连接到端口8888的构想是成功的,我可以发送到服务器和接收...当我ctrl + c客户端选择功能再次返回1,现在我的accept()失败。 .. 当我在端口6634上做同样的事情时,一切正常...代码在select()处停止并等待套接字准备好读取!

谁能告诉我为什么会发生这种情况?

采取附件看看我的代码

int main() 
    { 
     SOCKET   conn_request_skt; /* socket where connections are accepted */ 
     char   buf[RBUFLEN], buf1[RBUFLEN];  /* reception buffer */ 
     uint16_t  lport_n, lport_h, lport_n1, lport_h1; /* port where the server listens (net/host byte ord resp.) */ 
     int   bklog = 2;  /* listen backlog */ 
     SOCKET   s,s1;   
     int   result, n; 
     socklen_t addrlen; 
     struct sockaddr_in saddr, caddr;  /* server and client address structures */ 
     int optval,childpid,i; /* flag value for setsockopt */ 
     int connectcnt; /* number of connection requests */ 
     fd_set readfds; 

     /* Initialize socket API if needed */ 
     SockStartup(); 

     /* input server port number */ 
     lport_h=6634; 
     lport_n = htons(lport_h); 
     lport_h1=8888; 
     lport_n1 = htons(lport_h1); 

     /* create the socket */ 
     printf("Creating first socket\n"); 
     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
     if (s == INVALID_SOCKET) 
      err_fatal("socket() failed"); 
     printf("done, socket number %u\n",s); 

     /* bind the socket to any local IP address */ 
     saddr.sin_family  = AF_INET; 
     saddr.sin_port  = lport_n; 
     saddr.sin_addr.s_addr = INADDR_ANY; 
     showAddr("Binding to address first socket", &saddr); 
     result = bind(s, (struct sockaddr *) &saddr, sizeof(saddr)); 
     if (result == -1) 
      err_fatal("bind() failed"); 
     printf("done.\n"); 

     printf("Creating second socket\n"); 
     s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
     if (s1 == INVALID_SOCKET) 
      err_fatal("socket() failed"); 
     printf("done, socket number %u\n",s1); 

     /* bind the socket to any local IP address */ 

     saddr.sin_port=lport_n1; 

     showAddr("Binding to address second socket", &saddr); 
     result = bind(s1, (struct sockaddr *) &saddr, sizeof(saddr)); 
     if (result == -1) 
      err_fatal("bind() failed"); 
     printf("done.\n"); 


     /* listen */ 
     printf ("Listening at socket %d with backlog = %d \n",s,bklog); 
     result = listen(s, bklog); 
     if (result == -1) 
      err_fatal("listen() failed"); 
     printf("done.\n"); 

     printf ("Listening at socket %d with backlog = %d \n",s1,bklog); 
     result = listen(s1, bklog); 
     if (result == -1) 
      err_fatal("listen() failed"); 
     printf("done.\n"); 
for (;;) 
    { 


     FD_ZERO(&readfds);   /* initialize the fd set */ 
     FD_SET(s, &readfds); 
     FD_SET(s1, &readfds); /* add socket fd */ 
     printf("here \n"); 

     printf("result bifore select is %d \n", result); 
     result=select(s1+1, &readfds, 0, 0, 0); 

     printf("result after select is %d \n", result); 

     if(result<0) 
      { 
       err_fatal("select() failed"); 

      } 
     if(result>0) 
     { 

      if(FD_ISSET(s,&readfds)) 
      { 

       conn_request_skt=s; 
       /* accept next connection */ 
       addrlen = sizeof(struct sockaddr_in); 
       s = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen); 
       if (s == INVALID_SOCKET) 
       err_fatal("accept() failed"); 
       showAddr("Accepted connection from", &caddr); 
       printf("new socket: %u\n",s); 
       /* serve the client on socket s */ 
       for (;;) 
       { 
        n=recv(s, buf, RBUFLEN-1, 0); 
        if (n < 0) 
        { 
         printf("Read error\n"); 
         closesocket(s); 
         printf("Socket %d closed\n", s); 
         break; 
        } 
        else if (n==0) 
        { 
         printf("Connection closed by party on socket %d\n",s); 
         //closesocket(s); 
         break; 
        } 
        else 
        { 
         printf("Received line from socket %03d :\n", s); 
         buf[n]=0; 
         printf("[%s]\n",buf); 
         if(writen(s, buf, n) != n) 
         printf("Write error while replying\n"); 
         else 
         printf("Reply sent\n"); 
        } 
       } 
      } 


      if(FD_ISSET(s1,&readfds)) 
      { 
       conn_request_skt=s1; 
       /* accept next connection */ 
       addrlen = sizeof(struct sockaddr_in); 
       printf("bifore accept! \n"); 
       s1 = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen); 
       if (s1 == INVALID_SOCKET) 
       err_fatal("accept() failed"); 
       showAddr("Accepted connection from", &caddr); 
       printf("new socket: %u\n",s1); 
       /* serve the client on socket s */ 
       for (;;) 
       { 
        n=recv(s1, buf, RBUFLEN-1, 0); 
        if (n < 0) 
        { 
         printf("Read error\n"); 
         closesocket(s1); 
         printf("Socket %d closed\n", s1); 
         break; 
        } 
        else if (n==0) 
        { 
         printf("Connection closed by party on socket %d\n",s1); 
         //closesocket(s); 
         break; 
        } 
        else 
        { 
         printf("Received line from socket %03d :\n", s1); 
         buf[n]=0; 
         printf("[%s]\n",buf); 
         if(writen(s1, buf, n) != n) 
         printf("Write error while replying\n"); 
         else 
         printf("Reply sent\n"); 
        } 
       } 
      } 
     } 
    } 
} 

回答

2

第一个监听套接字时创建:

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

,然后将数据插座接受了:

conn_request_skt=s; 
s = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen); 

看到?下一个循环,当您要选择侦听器套接字时,s不再保存该套接字,而是(关闭的)数据套接字。

解决方案是为侦听套接字和数据套接字使用不同的变量(conn_request_skt只是混淆了该问题)。

1

你正在用accept()调用的结果覆盖你的套接字变量s1。因此,s1包含您实际读取的套接字的描述符。然后你关闭那个插座。但是在主循环的下一个过程中,你检查那个(现在是关闭的)描述符的可读性,这不起作用。

我认为最好不要在这种情况下重用变量。为实际连接套接字使用一个新变量,以便在s1中保留原始监听套接字。

相关问题