2014-01-21 107 views
0

這是一個簡單的代碼,我寫了。服務器響應端口2923,2924和2925上的連接。MultiSocket偵聽Linux套接字編程

當我運行該程序時,服務器只支持來自端口2923的CONNECTION。有人可以幫助我。 Thanku

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/time.h> 

void handle_client(int cliend_fd) 
{ 

    int ret = accept(cliend_fd, NULL, 0); 
    if (ret < 0) 
    { 
    printf("Accept Error\n"); 
    } 

    else 
    { 
    printf("Client Accepted\n"); 
    shutdown(ret, 2); 
    } 
} 

int main() 
{ 
    int count = 3; 
    int PORT = 2923; 

    struct sockaddr_in address; 
    int MasterSocket[count]; 
    int i = 0; 
    fd_set readfds; 

    int maxfd; 
    maxfd = -1; 
    int SelectSession; 

    struct timespec TimeOut; 
    TimeOut.tv_sec = 2; 
    TimeOut.tv_nsec = 2; 

    for (i = 0; i < count; i++) 
    { 
    MasterSocket[i] = socket(AF_INET, SOCK_STREAM, 0); 
    } 

    for (i = 0; i < count; i++) 
    { 
    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    address.sin_port = PORT + i; 
    if (bind(MasterSocket[i], (struct sockaddr *) &address, sizeof(address)) 
     < 0) 
    { 
     perror("Bind\n"); 
     getchar(); 
    } 

    printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT + i); 
    } 

    for (i = 0; i < count; i++) 
    { 
    if (listen(MasterSocket[i], 4) < 0) 
    { 
     perror("Listen"); 
     getchar(); 
     //return 1; 
    } 
    else 
    { 
     printf("Listening on Port %d---\n", PORT + i); 
    } 
    } 

    while (1) 
    { 
    FD_ZERO(&readfds); 
    int status; 

    for (i = 0; i < count; i++) 
    { 
     FD_SET(MasterSocket[i], &readfds); 
     if (MasterSocket[i] > maxfd) 
     { 
     maxfd = MasterSocket[i]; 
     } 
     printf("%d Added to FD_SET Descriptor %d \n\n", PORT + i, 
      MasterSocket[i]); 
    } 

    //status = 0; 
    printf("############Waiting for Connection\n"); 
    status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL); 
    if (status < 0) 
    { 
     perror("Status"); 
     getchar(); 
     return 1; 
    } 

    else if (status == 0) 
    { 
     printf("TimeOut occured\n"); 
    } 

    else 
    { 
     //printf("Status %d\n", status); 
     SelectSession = -1; 
     for (i = 0; i < count; i++) 
     { 
     //printf("Checking Set %d\n", i); 
     if (FD_ISSET(MasterSocket[i], &readfds)) 
     { 
      //printf("Matching Set %d\n", i); 
      SelectSession = MasterSocket[i]; 
      printf("SelectSession %d\n", MasterSocket[i]); 
      if (SelectSession == -1) 
      { 
      //shutdown (MasterSocket[i], 2); 
      //continue; 
      break; 
      } 
      else 
      { 
      printf("In Handle\n"); 
      handle_client(SelectSession); 
      getchar(); 
      } 

     } 
     else 
     { 
      printf("Not in FD_ISSET\n"); 

     } 
     } 
    } 

    /*for (i=0; i<count; i++) 
    { 
    shutdown (MasterSocket[i], 2); 
    } 
    */ 
    } 

    return 0; 
} 
+2

集'SO_REUSEADDR' – sujin

+1

你在程序執行過程中爲bind(),listen(),pselect()和/或accept()提供任何錯誤? – alk

+0

@alk no我沒有 –

回答

1

從while循環中刪除getchar()

pselect服務器等待得到一個字符後,所以它不允許再連接客戶端。

或者你有連接

每個客戶端後在服務器上輸入一個字符,並更改端口號,使用網絡字節順序htons

計劃:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/time.h> 

void handle_client (int cliend_fd) 
{ 
    int ret = accept(cliend_fd, NULL, 0); 
    if (ret < 0) 
     printf("Accept Error\n"); 
    else { 
     printf ("Client Accepted\n"); 
     shutdown (ret, 2); 
    } 
    return; 
} 

int main() 
{ 
    int count = 3, PORT = 8000, opt = 1, i = 0; 
    int MasterSocket[count]; 
    int maxfd = -1, SelectSession; 
    fd_set readfds; 
    struct sockaddr_in address; 

    struct timespec TimeOut; 
    TimeOut.tv_sec = 2; 
     TimeOut.tv_nsec = 2; 

    for(i=0; i<count; i++) 
    { 
     MasterSocket[i] = socket(AF_INET , SOCK_STREAM , 0); 
     printf("socket created : %d\n", MasterSocket[i]); 
    } 

    for(i=0; i<count; i++) 
    { 
     address.sin_family = AF_INET; 
     address.sin_addr.s_addr = inet_addr("192.168.1.4"); 
     address.sin_port = htons(PORT+i); 
     if(setsockopt(MasterSocket[i], SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {  
      perror("setsockopt1"); 
      return -1; 
     } 
     if (bind(MasterSocket[i], (struct sockaddr *)&address, sizeof(address)) < 0) { 
      perror ("Bind\n"); 
      return -1; 
     } 
     printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT+i); 
    } 

    for(i=0; i<count;i++) 
    { 
     if (listen(MasterSocket[i], 4) < 0) { 
       perror ("Listen\n"); 
       return -1; 
     } 
     else 
      printf("Listening on Port %d---\n", PORT+i);  
    } 

    while(1) 
    { 
     FD_ZERO(&readfds); 
     int status; 
     for (i = 0; i < count; i++) 
     { 
      FD_SET(MasterSocket[i], &readfds); 
      if (MasterSocket[i] > maxfd) 
       maxfd = MasterSocket[i]; 
     } 

     status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL); 
     if(status < 0) 
      perror("Status"); 
     /* else if(status == 0) 
      printf("TimeOut occured\n"); */ 
     else if(status > 0) { 
      for (i = 0; i < count; i++) 
      { 
       if (FD_ISSET(MasterSocket[i], &readfds)) { 
        SelectSession = MasterSocket[i]; 
        printf("SelectSession %d\n", MasterSocket[i]); 
        handle_client(SelectSession); 
        //getchar(); 
       } 
      } 
     } 
    } 
    return 0; 
}  
+0

您是否試過用我給出的答案代碼? – sujin

+0

工作中......感謝您的幫助\ m /。是的,我查找了'SO_REUSEADDR'和'getchar()',忽略了一個小細節。 'pselect'和'count + 1'不同於'maxfd + 1' –

2

此行

address.sin_port = PORT + i; 

應該

address.sin_port = htons(PORT + i); 

,以確保端口存儲在網絡字節順序。


你也應該close()已經關閉它,如果你不需要它了,用它來釋放系統資源associatee後套接字描述符。

+0

我已經這樣做了。 :-( –