2013-08-06 63 views
0

首先,我在C++中編寫代碼並運行在Linux/CentOS 6.4中。如何使用套接字不斷接受來自不同客戶端的多個消息?

因此,經過很長時間並閱讀了很多關於套接字的書籍,終於至少我的客戶端和服務器部分工作。

首先我想不斷接受來自不同客戶端的消息,我已經設置了客戶端,並且最終成功編譯了。現在我需要設置我的服務器,以便我可以正確測試。

我正在做的是用套接字實現餐飲哲學家問題,每個客戶/哲學家代表不同的過程。我正要經歷這一切,服務器將會跟蹤所有的事情,比如所有客戶的狀態。這太困難了,我現在剛剛創建了客戶端,只是將它們的狀態發送到服務器,然後服務器將它打印出來。

我正在考慮放置一個do/while循環來持續接受消息,但不知道我應該用什麼來停止循環。請注意,我將在我的客戶端中設置一個while循環,在經過一段時間後,該循環會停止。它應該關閉那個特定的客戶端。我的發球確實有一個信號,但我不確定它是否有效。

#include "helper.h" 
    char buffer[4096]; 
void sigchld_handler(int signo) 
{ 
    while (waitpid(-1, NULL, WNOHANG) > 0); 
} 
void client(int &newsock, int nread) 
{ 
do 
      { 

       int nread = recv(newsock, buffer,sizeof(buffer), 0); 
        puts(buffer); 


      }while(nread!=0); 
} 


int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in sAddr, cli_addr; 
    socklen_t client_len; 
    int listensock; 
    int newsock; 

    int result; 
    int nread=1; 
    pid_t childid; ; 
    int status; 

    if((listensock = socket(AF_INET, SOCK_STREAM, 0))<0) 
    { 
     perror("Problem in creating socket"); 
     exit(2); 
    } 


    sAddr.sin_family = AF_INET; 
    sAddr.sin_port = htons(3333); 
    sAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr)); 
    if (result < 0) { 
     perror("exserver2"); 
     return 0; 
    } 

    result = listen(listensock, 5); 
    if (result < 0) { 
     perror("exserver2"); 
     return 0; 
    } 

    signal(SIGCHLD, sigchld_handler); 

    while (1) { 
    client_len = sizeof(cli_addr); 
     newsock = accept(listensock,(struct sockaddr *)&cli_addr, &client_len); 
     if ((childid = fork()) == 0) { 
      printf("child process %i created.\n", getpid()); 
      close(listensock); 
      client(newsock, nread); 


      } 
      if(status<0) 
      { 
      printf("%s\n" "Read error"); 
      exit(1); 
      } 

      close(newsock); 

    } 
} 
+0

如果'recv()'返回0,則需要退出讀取循環,並且需要使用它返回的長度,而不是將整個緩衝區傳遞給'puts()'。 – EJP

+1

也許你應該看看選擇,而不是爲每個客戶分派 – Alexis

+0

那麼項目需要單獨的流程,並且從我從所有書籍中閱讀的內容來看,select並沒有真正做到這一點。 – user2644360

回答

1

你需要一個系統調用復像poll(2)(或舊的,過時的近,select(2)系統調用)。你可能想要使用一些(或實現你自己的)事件循環。見this & that回答。閱讀關於C10K problem

每個服務器都需要一個事件循環。

閱讀Advanced Linux Programming(或一些Posix網絡編程書籍)。

0

您可能只想在tcpserver下運行您的服務器程序(請參閱http://cr.yp.to/ucspi-tcp.html)。這將在客戶端連接到您的程序時(在您指定的端口上)生成一個新的程序實例。這樣,你可以專注於程序的核心邏輯,並讓tcpserver處理所有繁重的工作,直到套接字編程等.tcpserver將輸入從客戶端傳遞到你的程序的stdin,並從你的程序輸出stdout將被髮回給客戶。

相關問題