2012-12-16 7 views
1

我正在寫一個客戶端服務器應用程序,我使用輪詢多個客戶插座和標準輸入,在那裏我可以插入命令(例如之間復:停止服務器)。我相信我的代碼的結構(「邏輯」)是正確的,但它不是表現我希望它的方式:Ç - 使用輪詢插座(S)和標準輸入之間的複用 - 服務器

struct pollfd pfd[NSERVER]; //defined as 10 
pfd[0].fd = fileno(stdin); 
pfd[0].events = POLLIN; 
pfd[1].fd = socktfd; //server bind, listen socket 
pfd[1].events = POLLIN; 
struct sockaddr_storage remoteaddr; // client address 
socklen_t addrlen; 
char remoteIP[INET6_ADDRSTRLEN]; 
addrlen = sizeof remoteaddr; 
char buf[1024];  // buffer 
int pos=2; 

    while(poll(pfd,1,0) >= 0) 
{ 
    if(pfd[0].revents & POLLIN) { //stdin 
      //process input and perform command 
     } 
    if(pfd[1].revents & POLLIN) { 
     /* new connection */ 
     int connsockfd = accept(socktfd, (struct sockaddr *)&remoteaddr,&addrlen); 


      pfd[pos].fd=connsockfd; 
     } 
int i=2; 
//Loop through the fd in pfd for events 
    while (i<=NSERVER) 
    { 
     if (pfd[i].revents & POLLIN) { 
    int c=recv(pfd[i].fd, buf, sizeof buf, 0); 
      if(c<=0) { 
     if (c==0) 
    { 
       /* Client closed socket */ 
      close(pfd[i].fd); 
        }} 


    else 
      {//Client sent some data 
      c=send(pfd[i].fd,sbuff,z,0); 
      if (c<=0) 
     { 
      Error; 
     } 
     free(sbuff); 
     } 
     } 
     i++; 
     } 
     } 

我已經刪除了的recv裏面的一些代碼,併發送,使代碼更容易讀書。 它無法表現(它只是掛起,不接受連接或反應從標準輸入)。

注:我寧願使用輪詢選擇,所以請不要指向選擇:-)。

在此先感謝您的幫助。

+0

是你的插座阻塞或非阻塞?它掛在哪裏? – ninjalj

+0

非阻塞,它從一開始就掛起 - 我可以從stdin鍵入輸入,但不會被處理。相同的插座 –

+0

哪裏_exactly_它掛起?在'strace'或同等條件下運行它。 – ninjalj

回答

3
  1. 您應該設置每個pfd[i].fd = -1,所以它們最初被poll()忽略。
  2. poll(pfd, 1, 0)是錯誤的,應該至少是poll(pfd, 2, 0)甚至poll(pfd, NSERVER, 0)
  3. while(i<=NSERVER)應該while(i<NSERVER)

你的程序可能掛起,因爲你通過PFD數組,沒有初始化,containes爲.FD和.revents隨機值,所以想要發送()或recv循環()在一些可能阻塞的隨機FD上。在i<NSERVER循環中執行if(pdf[i].fd < 0) {i++; continue;}

您也不會在新接受的套接字上設置pfd[pos].events = POLLIN。除非你有東西要發送,否則不要設置POLLOUT,因爲它幾乎每次都會觸發。