2014-04-24 28 views
0

我有一個始終爲真的循環以允許其他客戶端連接。我遇到的問題是,如何不斷檢查共享內存以查看它是否更改以知道什麼時候關閉服務器?我放入的while循環工作,但不會讓任何其他客戶端連接後。問題是在while(1)循環中,它必須等待另一個客戶端在通過循環之前進行連接,但我需要它始終檢查共享內存,而不僅僅是在另一個客戶端連接時。不斷檢查共享內存在循環中更改

#include <sys/types.h> 
    #include <netinet/in.h> 
    #include <sys/socket.h> 
    #include <errno.h> 
    #include <stdio.h> 
    #include <unistd.h> 
    #include <stdlib.h> 
    #include <strings.h> 
    #include <sys/ipc.h> 
    #include <sys/shm.h> 
    #include <sys/wait.h> 

    struct sockaddr_in sn; 
    struct sockaddr from; 

    int main(int ac, char** other){ 
     int s, ns, sl, x = 22, pid; 
     char b[256]; 
     key_t key=137; 
     int size=1; 
     int shmflg=0; 
     int id=0,ok=0; 
     char shmstr[10]; 
     char istr[10]; 
     int *shmptr; 

     size=size*sizeof(int); 
     shmflg=IPC_CREAT | SHM_R | SHM_W; 
     id=shmget(key,size,shmflg); 
     sprintf(shmstr,"%d",id); 
     shmptr=shmat(id,0,0); 
     shmptr[0]=0; 

     s=socket(AF_INET, SOCK_STREAM,0); 
     if (s<0) { 
     printf("server socket error\n"); 
     exit(0);} 
     else {} 

     bzero((char *)&sn, sizeof(sn)); 
     sn.sin_family = AF_INET; 
     sn.sin_port = htons(3311); 

     if (bind(s,(struct sockaddr *)&sn,sizeof(sn))==-1){ 
     printf("server bind error %d\n",errno); 
     exit(0);} 
     else {} 

     listen(s,3); 
    ////////////////////////////////////**************************************** 
     while (1){ 
     sl=sizeof(from); 
     ns =accept(s,&from,&sl); 
     if (ns <0) { 
      printf("server accept error"); 
      exit(0);} 
     else {} 
     sprintf(b,"%d",ns); 
     if ((pid=fork()) == 0) { 
      sprintf(istr, "%d",ok); 
      execlp(other[1], other[1], b, shmstr, istr, (char*) NULL); 

     } 
     else { 
      while(shmptr[0]==0){}//allows the server to shut down but no more clients connect 
      close(s); 
      exit(0); 
      } 
     } 

     } 
    ////////////////////////////////////////////************************* 
     close(s); 
     return 0; 
    } 
+0

然後檢查您的輪詢循環中的所有條件。也使用'memset'而不是'bzero'它已經被棄用了。另外,如果你使用套接字爲什麼使用共享內存,爲什麼不在一個循環中調用accept併產生線程來處理請求呢? –

+0

我嘗試過,但它仍然不得不坐在ns = accept。我需要它在任何給定的時間和任何給定的客戶端設置共享內存爲0關閉服務器。它是一個項目的一部分,我們必須使用共享內存。 – Joe

+0

@Joe,共享內存有多少個線程?兩個以上?也許代碼可以實現一個信號量或信號,你的線程可以阻止(即:等待)? –

回答

1

如果我正確理解你的話,非阻塞套接字就是你要找的。

[編輯:] 使用select

http://www.scottklement.com/rpg/socktut/nonblocking.html

非阻塞插座也可在與選擇() API結合使用。事實上,如果你達到了一個點,你實際上想在先前標記爲「非阻塞」的套接字上等待 數據,那麼你可以通過首先調用select(), 來模擬阻塞recv()。通過recv()。

+0

是的!謝謝! – Joe