我这里有一个UDP服务器,它监听端口9001。我已经定义了接收数据缓冲区的最大块大小为4096。
我的问题是,当客户端发送一个大数据(例如20000字节)时,我只接收到我定义的块大小。我有一个无休止的循环,它将不断地从客户端接收数据。
这是我的代码:

  void TdaServer::StartServer()
  {
      #ifdef LOGGING_ENABLED
      LOG_MSG("WARNING: StartServer called");
      #endif

       struct sockaddr_in cli;
       //int socketId;
       socklen_t size;

       socketId=socket(AF_INET, SOCK_DGRAM, 0);
       if (socketId < 0)
       {
          #ifdef LOGGING_ENABLED
          LOG_MSG("ERROR: failed to create socket!");
          #endif
       }


       int length = sizeof(server);
       bzero(&server,length);
       server.sin_family        =AF_INET;
       server.sin_addr.s_addr   =INADDR_ANY;
       int port = atoi(Config::GetEnv("nfc_demo_port").c_str());
       if(port==0)
          port = 9001;

       server.sin_port          =htons(port);

       if (bind(socketId,(struct sockaddr *)&server,length)<0)
       {
          #ifdef LOGGING_ENABLED
          LOG_MSG("Error binding!");
          #endif
       }

       size = sizeof(struct sockaddr_in);

       thread_parm_t *parm=NULL;
       parm             = new thread_parm_t;
       parm->socketId   = socketId;
       parm->client     = cli;
       parm->size       = size;
       #ifdef LOGGING_ENABLED
       LOG_MSG("TDA server started, socket id: %i, port: %d", socketId, port);
       #endif

       pthread_attr_t attr;
       pthread_t clientthread;
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
       pthread_create(&clientthread, &attr, Receive, (void *)parm);
  }

  void *Receive(void *parm)
  {
    thread_parm_t *p = (thread_parm_t *)parm;
    char buffer[MAX_CHUNK_SIZE+1]; //MAX_CHUNK_SIZE = 4096
    string data="";
    extern int errno;
    while(true)
    {
        #ifdef LOGGING_ENABLED
        LOG_MSG("-TdaServer waiting for data...");
        #endif

        int n = recvfrom(p->socketId,buffer,MAX_CHUNK_SIZE,0,
                (struct sockaddr *)&p->client, &p->size); //wasn't able to receive large data ex. 20000 bytes

        #ifdef LOGGING_ENABLED
        LOG_MSG("-TdaServer received data size: %d", n);
        #endif
        if(n>0)
        {
            data = data.append(string(buffer).substr(0, n));
            #ifdef LOGGING_ENABLED
            LOG_MSG("-TdaServer [%s] n: %d < mcs: %d, %s", inet_ntoa(p->client.sin_addr), n, MAX_CHUNK_SIZE, (n<MAX_CHUNK_SIZE?"true":"false"));
            #endif

            if(n<MAX_CHUNK_SIZE)//received complete
            {
                #ifdef LOGGING_ENABLED
                LOG_MSG("-TdaServer received data size: %d, complete!", n);
                #endif

                TcbMgrConnection::SendResponse(data.c_str());
                data = "";
            }
        }
        else if(n<0)
        {
            #ifdef LOGGING_ENABLED
            LOG_MSG("TdaServer: Error reading from socket");
            #endif
        }
        else
        {
            if(n==0)
            {
                #ifdef LOGGING_ENABLED
                LOG_MSG("IPServer: client %d disconnected", p->socketId);
                #endif
                //break;
            }
        }
    }
    close(p->socketId);
    return NULL;
  }

这是用VB.NET编写的UDP客户端代码
Private Sub cmdSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSend.Click

    Dim pRet As Integer

    Try
        GLOIP = IPAddress.Parse(txtIP.Text)
        GLOINTPORT = txtPort.Text
        udpClient.Connect(GLOIP, GLOINTPORT)
        bytCommand = Encoding.ASCII.GetBytes(txtMessage.Text)
        pRet = udpClient.Send(bytCommand, bytCommand.Length)
        Console.WriteLine("No of bytes send " & pRet)
        txtInfo.Text = "INFORMATION" & vbCrLf & "No of bytes send " & pRet
    Catch ex As Exception
        Console.WriteLine(ex.Message)
        txtInfo.Text = txtInfo.Text & vbCrLf & ex.Message
    End Try
End Sub

我做得对吗?请帮忙。。提前谢谢

最佳答案

我不建议发送大的UDP包。UDP包的数据大小被限制在1300字节左右(假设路由器的典型MTU是1500或更少),任何较大的数据都被路由器分割,然后重新组装。
如果任何路由器的方式不允许碎片,您的所有数据包将被丢弃。如果任何片段丢失,整个包将被丢弃,即使在许多情况下仍然可以使用其余的数据。
传输较大数据块的更好方法是,手动将它们分割成约1250字节的片段,然后在接收器处将片段粘合在一起。请记住,其中一些可能会丢失或无序到达。

关于c++ - C/C++ UDP服务器问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7061238/

10-15 13:31