我这里有一个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/