2012-11-22 33 views
2

我面臨一個奇怪的問題,也許這很簡單,但是我缺乏多少套接字知識也無濟於事。選擇總是返回0當在不同的程序中運行時

我已經創建了一個套接字程序,並且它在單獨的程序中運行,即在單獨的主程序中作爲獨立的exe運行時可以很好地工作。正如你在代碼中看到的那樣,在這個單獨的程序中運行時,返回的套接字fd始終爲3。

當我複製相同的一段代碼,並將其集成到另一個服務器程序中,該程序打開了它自己的fd後,無論如何select都始終返回0。在這種情況下創建的fd與我的程序始終是6.

請參閱下面的程序。這段代碼沒有問題,只是當它在另一臺服務器上運行時,select總是返回0.

當程序中已經存在一個新的UDP套接字時,我可以創建一個新的UDP套接字fd。 爲什麼會發生這種情況,當我的套接字fd是不同的,然後已經在程序中打開。

爲什麼會發生這種情況,任何人都可以請指導我做什麼或任何指針會有所幫助。

#define MY_TIMEOUT_S 5 
    int mySock; 
    if ((mySock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 
     perror("Cannot create UDP socket"); 
     return -1; 
    } 

    struct sockaddr_in myAddr; 
    myAddr.sin_family  = AF_INET; 
    myAddr.sin_port   = 0; 
    myAddr.sin_addr.s_addr = INADDR_ANY; 
    memset(&(myAddr.sin_zero), '\0', 8); 
    if (bind(mySock, (struct sockaddr*)&myAddr, 
      sizeof(struct sockaddr)) == -1) { 
     perror("Cannot bind UDP socket to desired port"); 
     close(mySock); 
     return -1; 
    } 

    // here send to remote target host on udp socket and port 

    char buf[MAX_UDP_PACKET_SIZE]; 
    struct sockaddr_in theirAddr; 
    int addrLen = sizeof(struct sockaddr); 

    fd_set readSet, curReadSet; 
    FD_ZERO(&readSet); 
    FD_SET(mySock, &readSet); 
    int maxFD = mySock; 
    while (true) { 
     struct timeval timeOutTV = {MY_TIMEOUT_S, 0}; 

     memcpy(&curReadSet, &readSet, sizeof(fd_set)); 

     int selectRet = select(maxFD+1, &curReadSet, NULL, NULL, &timeOutTV); 
     cout<<"select value =" <<selectRet<<endl; 

     if (selectRet == -1) { 
      if (errno == EINTR) { 
       continue; // Interrupted by signal, retry 
      } 
      close(mySock); 
      return -1; 

     } else if (selectRet == 0) { 
      close(mySock); 
      return -1; 
     } 
     if (FD_ISSET(mySock, &curReadSet)) { 
      int numBytes = recvfrom(mySock, buf, MAX_UDP_PACKET_SIZE, 0, 
        (struct sockaddr*)&theirAddr, (socklen_t*)&addrLen); 
      if (numBytes == -1) { 
       close(mySock); 
      } 

     } 
    } 

從lsof的輸出端增加了一些細節

1)這是我必須把我的數據 須藤lsof的-a -p 16061

目標16061根3R FIFO 0,8目標0t0 153467管
目標16061根4U的IPv4 153470 0t0 UDP *:3290
目標16061根5U襪子0,6 0t0 153471不能識別協議
目標16061根6U的IPv4 153472 0t0 TCP *:3290(LISTEN)
目標16061根7U原料0t0 153473 00000000:0001-> 00000000:0000 ST = 07

2)這是我的當在一個單獨的EXE運行,其中僅該被內部主運行上面的代碼的代碼 作爲FD = 3作品細

須藤lsof的-a -p 16112

MYPROG 16112根0U CHR 136,4 0t0 7的/ dev/PTS/4
MYPROG 16112根1U CHR 136,4 0t0 7/dev/pts/4
myProg 16112 root 2u CHR 136,4 0t0 7/dev/pts/4
MYPROG 16112根3U的IPv4 153564 0t0 UDP *:60503

3)這是我整合我的相同上述片的,其獨立地工作的代碼的Web服務器,但不是現在

這是的輸出我運行Web服務器

webServ 18431根3U UNIX 0xc09f9b00 0t0 157975插座
webServ 18431根的4U的IPv4 157976 0t0 UDP *:8080
webServ 18431根,5μ的IPv4 157977 0t0 TCP *:8080(LISTEN)

現在我發送請求,並在服務器端執行我的新的集成的代碼,我把一個無限循環,並沒有關閉套接字只是爲了顯示lsof的輸出我的積分

webServ 18449後

4)輸出根3U UNIX 0xc09f9b00 0t0 157975插座
webServ 18449根4U的IPv4 157976 0t0 UDP *:8080
webServ 18449根5U的IPv4 157977 0t0 TCP *:8080(LISTEN)
webServ 18449根6U的IPv4 158389 0t0 UDP *:48057

唯一的區別是w母雞集成到服務器的插座FD是不同的,這是唯一的區別。

希望這有助於回答我的問題。

我不知道爲什麼會發生這種情況。請幫忙

+0

也許用'maxFd + 1'選擇'會有幫助嗎? –

+0

添加了一些來自lsof的細節。 – user1621776

回答

0

也許selectmaxFd + 1會有幫助嗎?

編輯:我再次查看了你的代碼(儘管你現在可能已經自己解決了它)。我有三點建議。

首先,當您bind插座,myAddr.sin_port0。所以選擇一個短暫的端口號。此端口號不同,您MYPROG和webServ程序之間:

myProg 16112 root 3u IPv4 153564 0t0 UDP *:60503 
webServ 18449 root 6u IPv4 158389 0t0 UDP *:48057 

所以我很困惑的是你已經使用的端口號發送UDP圖來MYPROG。

其次,select的超時時間爲5秒,之後關閉套接字並消失。你怎麼知道你會在打開端口5秒內收到一個數據包?爲確保這一點,發送程序需要(例如)每4秒或更少的時間連續嘗試發送一個數據包,這看起來並不合理。

第三,這很可能是一個小點,但也可能會被你的問題,在:

 if (numBytes == -1) { 
      close(mySock); 
     } 

你忽略你在其他地方使用的return -1;,所以你會停留在一個無限循環,如果recvfrom回報一個錯誤,如EINTR。此外,在這裏和其他地方打電話perror會很好。

最後,評論:

// here send to remote target host on udp socket and port 

不正確,你接收

+0

我很抱歉,實際上我嘗試了不同的選項,所以我將其更改爲maxFD,但我也嘗試使用maxFD + 1,如指定的那樣,它在獨立程序中運行時完美運行。編輯主帖子 – user1621776

0

作出這樣的:

int maxFD = mySock + 1; 

man page for select(2)說:

int select(int nfds, fd_set *readfds, fd_set *writefds, 
      fd_set *exceptfds, struct timeval *timeout); 

NFDs的在任何三套,加1的編號最大的文件描述符。

+0

我很抱歉,實際上我嘗試了不同的選項,所以我將其改爲maxFD,但我也嘗試使用maxFD + 1,如指定的那樣,它在獨立程序中運行時完美運行。 – user1621776