【问题标题】:select() wont timeout after send()select() 在 send() 之后不会超时
【发布时间】:2013-03-21 21:41:52
【问题描述】:

我开始锁定套接字编程并遇到了一些麻烦: 我在下面创建了一个小程序,它通过 udp 发送消息,并在可能的情况下循环接收消息。我想稍后尝试使用多个套接字,所以我使用select()

当我使用我的127.0.0.1 时,select() 在第一个循环中给出了超时(在send() 之后),但之后它总是返回1,表明套接字是可读的,但没有收到消息:

//C++
WSADATA wsa;
SOCKADDR_IN RemoteAddr;
SOCKADDR_IN OwnAddr;
SOCKET UDP_Socket1;
fd_set m_Fds;
struct timeval m_Timeout;
int iRemoteAddrLenght = sizeof(SOCKADDR_IN);
int i = 0;

//--Init
WSAStartup (MAKEWORD (2,2), &wsa);
UDP_Socket1 = socket(AF_INET, SOCK_DGRAM, 0);
m_Timeout.tv_sec = 2;
m_Timeout.tv_usec = 0;

RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons (2002);
RemoteAddr.sin_addr.s_addr = inet_addr("127.0.0.1");   

OwnAddr.sin_family = AF_INET;
OwnAddr.sin_port = htons (2003);
OwnAddr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(UDP_Socket1, (SOCKADDR*) &OwnAddr, sizeof(OwnAddr));

for(;;)
{
    //..//
    //--send
    sendto(UDP_Socket1, sSend.c_str(), strlen(sSend.c_str()), 0 ,  (SOCKADDR*)&RemoteAddr, sizeof(RemoteAddr));

    //--select & recv
    FD_ZERO(&m_Fds);
    FD_SET(UDP_Socket1,&m_Fds);
    i = select(sizeof(m_Fds)*8, &m_Fds, NULL, NULL, &m_Timeout);
    if(i > 0)
    {
        recvfrom(UDP_Socket1, m_szBuff, 256, 0, (SOCKADDR*) &RemoteAddr, &m_iRemoteAddrLenght);
    } //if
    else if(i < 1)        // "0" in 1st loop, then "1" =(
    {
        cout << "Udp Timeout" << endl;    
    } //else if
} //for

send 返回56(发送字节) WSAGetLastError: 0

recvfrom 返回-1 WSAGetLastError: 10054

感谢您提供有关为什么 select() 在应该超时时返回 1 的帮助

【问题讨论】:

  • 在哪里创建socket,你必须告诉它你想要一个UDP:第三个参数必须是IPPROTO_UDP
  • UDP_Socket1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 还是一样
  • 如果 recvfrom 返回 -1 和 WSAGetLastError 返回 10054 (WSAECONNRESET),根据 MSDN (msdn.microsoft.com/en-us/library/windows/desktop/ms740120.aspx),这意味着发送实际上失败了(ICMP 端口不可达)。尝试通过传递另一个 fd_set 作为第四个参数来检查选择中的错误。
  • ´i = select(sizeof(m_Fds)*8, NULL, NULL, &m_Fds, &m_Timeout);´ 返回“0”;当我用我的套接字添加第二个 fd_set 并将其传递给 select 时:'int i = select(1,&m_Fds, NULL, &m_Fds2, &m_Timeout);' 它仍然返回“1”,你会这么好心并解释为什么recvfrom() 关心 sendto()?我以为 Udp 只是发送一条消息,以后不关心它......?提前致谢
  • sry,编辑时间过长:i = select(sizeof(m_Fds)*8, NULL, NULL, &amp;m_Fds, &amp;m_Timeout); 返回“0”;当我用我的套接字添加第二个 fd_set 并将它传递给 select 时:int i = select(1,&amp;m_Fds, NULL, &amp;m_Fds2, &amp;m_Timeout); 它仍然返回“1”。 ......你会这么好心并解释为什么recvfrom()关心sendto()吗?我以为 Udp 只是发送一条消息,以后不关心它......?提前致谢

标签: c++ sockets select timeout udp


【解决方案1】:

对于 UDP,您可以忽略这些类型的错误。有些操作系统会报告它们,有些则不会。它们基本上没有意义。

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 2010-09-18
    • 2011-07-18
    • 1970-01-01
    • 2018-06-27
    • 2021-07-16
    • 2020-10-06
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多