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

时间:2013-12-02 14:00:58

标签: c++ udp

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

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

#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: %d\n",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秒。

谢谢你, 此致

1 个答案:

答案 0 :(得分:0)

请勿在客户端上使用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");
    }

最后,您可能需要查看flushing UDP buffers