c++UDP中继应用程序延迟



我想从服务器应用程序(在同一台计算机上)接收UDP数据包,并将其转发到不同端口上的UDP接收应用程序。服务器应用程序不是我的,我也没有源代码。

UDP接收应用程序是一个Java应用程序。如果我将Java应用程序直接绑定到服务器应用程序端口,则延迟非常低,但如果我将其连接到中继应用程序端口上,则延迟几乎为1秒。接收端口必须是非阻塞的。

#define rcv_length 160
fd_set fds;
int n;
struct timeval tv;
void CMClient::startUDPListener(){
  CMport_number = 32200;    
  remoteAddrLen = sizeof(struct sockaddr_in);
  if (WSAStartup(0x0101, &CMw) != 0)
  {
    fprintf(stderr, "Could not open Windows connection.n");
    exit(0);
  } 
      CMsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (CMsd == INVALID_SOCKET)
  {
    fprintf(stderr, "Could not create socket.n");
    WSACleanup();
    exit(0);
  }
  CMserver.sin_family = AF_INET;
  CMserver.sin_port = htons(CMport_number);
  CMserver.sin_addr.s_addr = inet_addr("127.0.0.1");
  long rc=bind(CMsd,(SOCKADDR*)&CMserver,sizeof(SOCKADDR_IN));
  if(rc==SOCKET_ERROR)
  {
    printf("Error: bind code: %dn",WSAGetLastError());     
  }
}
void CMClient::updateData(UDPServer* svr, int CMnr){    
FD_ZERO(&fds);
FD_SET(CMsd, &fds);
tv.tv_sec = 0;
tv.tv_usec = 1;
n = select ( CMsd, &fds, NULL, NULL, &tv ) ;
if (FD_ISSET(CMsd, &fds))
    {
    FD_CLR(CMsd,&fds);
    char* rcvBuffer = new char[rcv_length];
    long rc=recv(CMsd,rcvBuffer,rcv_length,0);      //receive
    if(rc!=SOCKET_ERROR)
    {
        rcvBuffer[0] = CMnr;            
        sendto(svr->sd, (char*)rcvBuffer, rcv_length, 0, (struct sockaddr*)&svr->server, sizeof(svr->server)) != (int)sizeof(rcvBuffer);            //send      
    }       
    if(rcvBuffer)
        delete [] rcvBuffer;
    }   
}

要发送到Java应用程序的UDP服务器初始化如下:

void UDPServer::startUDPServer(){
    if (WSAStartup(0x0101, &w) != 0)
    {
        fprintf(stderr, "Could not open Windows connection.n");
        exit(0);
    }       
    sd = socket(AF_INET, SOCK_DGRAM, 0);    
    if (sd == INVALID_SOCKET)
    {
        fprintf(stderr, "Could not create socket.n");
        WSACleanup();
        exit(0);
    }       
    server.sin_family = AF_INET;
    server.sin_port = htons(port_number);
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)
    {
        fprintf(stderr, "Could not connect name to socket.n");     
        stopUDPServer();
    }
}

主要呼叫

UDPServer* udpsvr;
udpsvr = new UDPServer;
udpsvr->startUDPServer();
while(1){
    CM->updateData(udpsvr, CMid);
}

如果能为我提供帮助,我将不胜感激。从Java应用程序接收到的数据是正确的,但延迟了约1秒。

谢谢,问候

不要在客户端上使用bind()。使用connect()

总结,对于UDP:

服务器:

  • socket()
  • bind()

客户:

  • socket()
  • connect()

服务器代码示例:

    // socket()
    fd_ = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd_ < 0) {
            throw std::runtime_error ("Client socket error");
    }
    // connect()
    struct sockaddr_in serv_addr;
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);
    struct in_addr addr;
    inet_aton(address.c_str(), &addr);
    bcopy(&addr, &serv_addr.sin_addr.s_addr, sizeof(addr));
    if (connect(fd_, (struct sockaddr *) &serv_addr,
                                    sizeof(serv_addr)) < 0) {
            ::close(fd_);
            throw std::runtime_error ("Client socket error");
    }

客户端代码示例:

    // socket()
    fd_ = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd_ < 0) {
            throw std::runtime_error ("Client socket error");
    }
    // connect()
    struct sockaddr_in serv_addr;
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);
    struct in_addr addr;
    inet_aton(address.c_str(), &addr);
    bcopy(&addr, &serv_addr.sin_addr.s_addr, sizeof(addr));
    if (connect(fd_, (struct sockaddr *) &serv_addr,
                                    sizeof(serv_addr)) < 0) {
            ::close(fd_);
            throw std::runtime_error ("Client socket error");
    }

最后,您可能想了解一下刷新UDP缓冲区的情况。

最新更新