Windows 通过UDP延迟从Linux到WinXP

Windows 通过UDP延迟从Linux到WinXP,windows,linux,networking,sockets,udp,Windows,Linux,Networking,Sockets,Udp,我写的UDPSocket包装有问题。我有一个高带宽低延迟的本地网络,通过它我来回发送UDP数据包。我不太担心数据包到达的可靠性,但是数据包到达的速度如此之快是非常重要的。以下是设置套接字的相关代码: bool UDPSocket::create() { int on = 1; #ifdef WIN32 if(WSAStartup(MAKEWORD(1,1), &SocketInfo) != 0) { MessageBox(NULL, "Cannot ini

我写的UDPSocket包装有问题。我有一个高带宽低延迟的本地网络,通过它我来回发送UDP数据包。我不太担心数据包到达的可靠性,但是数据包到达的速度如此之快是非常重要的。以下是设置套接字的相关代码:

bool UDPSocket::create() {
    int on = 1;
#ifdef WIN32
    if(WSAStartup(MAKEWORD(1,1), &SocketInfo) != 0) {
        MessageBox(NULL, "Cannot initialize WinSock", "WSAStartup", MB_OK);
    }
#endif
    m_sock = socket(PF_INET, SOCK_DGRAM, 0);
#ifdef WIN32
    if(setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == SOCKET_ERROR)
        return false;
#else
    if(setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1)
        return false;
#endif
    addrLen = sizeof(struct sockaddr);
    return true;
}

bool UDPSocket::bind(const int port) {
    if(!is_valid())
        return false;
    m_addr.sin_family = AF_INET;
    m_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    m_addr.sin_port = htons(port);

    if(::bind(m_sock, (struct sockaddr*)&m_addr, sizeof(m_addr))<0) {
        std::cout << "UDPSocket: error on bind" << std::endl;
        return false;
    }
    return true;
}
bool UDPSocket::send(const std::string s) const {
    const char* buf = s.c_str();

    ::sendto(m_sock, buf, strlen(buf), 0, (const sockaddr*)&clientAddr, addrLen);
    return true;
}

bool UDPSocket::setDestination(const std::string ip, const int port) {
    memset(&clientAddr, 0, sizeof(clientAddr));

    clientAddr.sin_family = AF_INET;
    clientAddr.sin_addr.s_addr = inet_addr(ip.c_str());
    clientAddr.sin_port = htons(port);

    return true;
}

int UDPSocket::recv(std::string& s) const {
    char buffer[MAXRECV + 1];
    struct timeval tv;
    fd_set fdset;
    int rc, nread;

    memset(&buffer, 0, sizeof(buffer));

    FD_ZERO(&fdset);
    FD_SET(m_sock, &fdset);

    tv.tv_sec = 0;
    tv.tv_usec = m_timeout;

    rc = select(m_sock + 1, &fdset, (fd_set *) 0, (fd_set *) 0, &tv);

    if(FD_ISSET(m_sock, &fdset)) {
#ifdef WIN32
        nread = ::recvfrom(m_sock, buffer, MAXRECV, 0, (sockaddr*)&clientAddr, const_cast< int * __w64 >(&addrLen));
#else
        nread = ::recvfrom(m_sock, buffer, MAXRECV, 0, (sockaddr*)&clientAddr, (socklen_t*)&addrLen);
#endif
        if(nread < 0) {
            return -1;
        } else if(nread == 0) {
            return 0;
        }
        s = std::string(buffer);
        return nread;
    } else {
        return 0;
    }
}
void UDPSocket::set_non_blocking(const bool b) {
    mNonBlocking = b;
#ifdef WIN32
    u_long argp = b ? 1 : 0;
    ioctlsocket(m_sock, FIONBIO, &argp);
#else
    int opts = fcntl(m_sock, F_GETFL);
    if(opts < 0) return;
    if(b)
        opts |= O_NONBLOCK;
    else
        opts &= ~O_NONBLOCK;

    fcntl(m_sock, F_SETFL, opts);
#endif
}
bool-UDPSocket::create(){
int on=1;
#ifdef WIN32
if(WSAStartup(MAKEWORD(1,1),&SocketInfo)!=0){
MessageBox(NULL,“无法初始化WinSock”,“WSAStartup”,MB_OK);
}
#恩迪夫
m_sock=socket(PF_INET,sock_DGRAM,0);
#ifdef WIN32
if(setsockopt(m_sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on))==SOCKET\u错误)
返回false;
#否则
if(setsockopt(m_sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on))=-1)
返回false;
#恩迪夫
addrLen=sizeof(结构sockaddr);
返回true;
}
bool UDPSocket::bind(const int port){
如果(!is_valid())
返回false;
m_addr.sinu family=AF_INET;
m_addr.sin_addr.s_addr=htonl(在任何情况下);
m_addr.sin_port=htons(port);

如果(::bind(m_sock,(struct sockaddr*)和m_addr,sizeof(m_addr))您是否尝试了所有四种组合(linux->linux,win->linux,linux->win,win->win)?哪些有延迟,哪些没有


另外,使用数据包嗅探器(如
tcpdump
或wireshark)查看延迟是在连接之前还是之后。

这不是一个直接的答案。可能是您可以尝试这样的工具,它可以测试tcp和udp性能。并且,您还可以检查它们的源代码,这是公共域。

如果您有时间进行实验,请尝试IOCP版本的代码


我从不相信win select的实现,因为它有64个套接字限制。

一位名叫迈克·辛普森的先生还不能发表评论,所以遇到了同样的问题。如果你仍然有兴趣解决这个问题,你能给他打个电话吗mikes@ioindustries.com请,谢谢你。如果没有,就没什么害处了。