簡體   English   中英

C套接字編程:調用recv()會改變我的套接字文件描述符?

[英]C socket programming: calling recv() changes my socket file descriptor?

嘿所有,我有recv()這個奇怪的問題。 我正在編程客戶端/服務器,其中客戶端發送()消息(結構准確)和服務器recv()它。 我也在使用多個套接字和select()。

while(1)
{
    readset = info->read_set;
    info->copy_set = info->read_set;

    timeout.tv_sec = 1; 
    timeout.tv_usec = 0; // 0.5 seconds

    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);

    if (ready == -1)
    {
        printf("S: ERROR: select(): %s\nEXITING...", strerror(errno));
        exit(1);
    }
    else if (ready == 0)
    {
        continue;
    }
    else
    {
        printf("S: oh finally you have contacted me!\n");
        for(i = 0; i < (info->max_fd+1); i++)
        {

            if(FD_ISSET(i, &readset)) //this is where problem begins
            {
                printf("S: %i is set\n", i);
                printf("S: we talking about socket %i son\n", i);  // i = 4
                num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);
                printf("S: number of bytes recieved in socket %i is %i\n", i, num_bytes); // prints out i = 0 what??

                if (num_bytes == 0)
                {
                    printf("S: socket has been closed\n");
                    break;
                }
                else if (num_bytes == -1)
                {
                    printf("S: ERROR recv: %d %s \n", i, strerror(errno));
                    continue;
                }
                else                    
                {
                    handle_request(arg, &msg);
                    printf("S: msg says %s\n", msg->_payload);
                }
            } // if (FD_ISSET(i, &readset)
            else
                printf("S:  %i is not set\n", i);
        } // for (i = 0; i < maxfd+1; i++) to check sockets for msg
    } // if (ready == -1)   

    info->read_set = info->copy_set;
    printf("S: copied\n");

} 

read_set的問題是在read_set ,0~3沒有設置,4是。 那樣就好。 但是當我打電話給recv()i突然變成了0.為什么會這樣? 對我來說,為什么recv()會獲取套接字文件描述符號並修改為另一個數字是沒有意義的。 這是正常的嗎? 我錯過了什么嗎?

S:  0 is not set
S:  1 is not set
S:  2 is not set
S:  3 is not set
S: 4 is set
S: we talking about socket 4 son
S: i is strangely or unstrangely 0
S: number of bytes recieved in socket 0 is 40

這就是打印出來的東西。

recv無法修改其第一個參數,因為它是按值獲取的。

您沒有顯示您聲明msgi ,但是基於此行

printf("S: msg says %s\n", msg->_payload);

msg上使用->運算符的地方,我假設它可能是這樣的:

struct somestruct* msg = malloc(sizeof(struct somestruct));
int i;

然后你這樣做:

num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);

請注意, msg 已經是指針,因此&msg指向指針的指針

那么這將完成是接收數據,並試圖將其存儲在地方, msg 指針本身,而不是地方, msg 通常,指針只有4個字節長,因此如果您收到的字節數超過4個,這將溢出存儲空間。 如果在msg之后在堆棧上聲明了i ,則很可能它被此溢出覆蓋,並且它恰好被接收到的數據包中的所有零字節覆蓋。

由於msg已經是指針,因此請更改接收行以消除多余的間接:

num_bytes = recv(i, msg, MAX_MSG_BYTE, 0);

同樣,您可能需要考慮對該行進行相同的更改

handle_request(arg, &msg)

如果handle_request函數實際上並不期望指向指針。

我的第一個猜測是sizeof(msg) < MAX_MSG_BYTE ,當recv溢出msg它會破壞i

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM