select 函数在 Windows Phone 平台上返回 -1

select function returning -1 on Windows Phone platform

我正在努力使用 select 函数。如果我只传递 readfds 和 exceptfds 参数,该函数工作正常,但是当我传递 writefds 参数时,select 函数 returns -1 和 WSAGetLastError returns 错误代码 10022 指出:"Some invalid argument was supplied".

此函数用于多平台项目中的函数,唯一出现此问题的平台是Windows Phone 平台。其余平台无此功能问题

int result = 0;


fd_set rset;
fd_set wset;
fd_set eset;

FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);

for(int i = 0; i<events.size(); i++){
    if(read){
         FD_SET(events[i]->rfd, &rset);
         FD_SET(event[i]->rfd, &eset);
    }

    if(write){
         FD_SET(events[i]->rfd, &wset);
        FD_SET(event[i]->rfd, &eset);
    }
}

int number = event.size();
fd_set rset_copy = rset;
fd_set wset_copy = wset;
fd_set eset_copy = eset;
timeval t;
t.tv_sec = 0;
t.tv_usec = 0;

result = select(number, &rset_copy,&wset_copy,&eset_copy,&t);

编辑

已将传递的时间值的名称从 "tv" 更正为 "t"。

假设这只是整个代码的一部分。我不知道它在 visual c 和 Windows Phone 中是否会有所不同,但这可能会有所帮助。

result = select(number, &rset_copy,&wset_copy,&eset_copy,&tv);

您在声明 timeval t 时传递了 &tv。这是一个编译时错误。我假设您的代码不同。

  • 检查读取或写入是否大于 0
  • 您确定所有事件[i]->rfd 都是套接字的有效文件描述符吗?
  • 你包括 Winsock2.h 吗?
  • 尝试使用 null 而不是 &t(或 tv)来阻止 select:

result = select(number, &rset_copy,&wset_copy,&eset_copy,null);

您的 timeval 变量名为 t,但您将另一个名为 tv 的变量传递给 select() 的最后一个参数。根据 select() documentation:

WSAEINVAL
The time-out value is not valid, or all three descriptor parameters were null.

此外,如果 readwrite 为假,请不要将相应的 fd_set 传递给 select(),而是传递 NULL。

旁注:

  1. select() 的第一个参数在 Windows 平台上被忽略(其他平台确实使用它),所以只需将其设置为 0。您没有传递正确的值无论如何。

  2. 不需要复制 fd_set 结构,因为它们是局部变量。

  3. write 为真时,您确定 ->rfd 是存储在 wset 中的正确套接字吗? event[i] 声明的到底是什么?是否有 ->wfd 字段?

试试这个:

if ((!events.empty()) && (read || write))
{
    int result = 0;

    fd_set rset, *prset = NULL;
    fd_set wset, *pwset = NULL;
    fd_set eset;

    FD_ZERO(&rset);
    FD_ZERO(&wset);
    FD_ZERO(&eset);

    for(int i = 0; i < events.size(); i++)
    {
        if (read) FD_SET(events[i]->rfd, &rset);
        if (write) FD_SET(events[i]->rfd, &wset);
        FD_SET(event[i]->rfd, &eset);
    }

    if (read) prset = &rset;
    if (write) pwset = &wset;

    timeval t;
    t.tv_sec = 0;
    t.tv_usec = 0;

    result = select(0, prset, pwset, &eset, &t);
    //...
}