C/ c++ UDP服务器问题
C/C++ UDP Server Problem
我这里有一个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;
}
这里是UDP客户端代码,用VB编写。净
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
我做的对吗?请帮助. .提前感谢
这就是recvfrom()的工作原理
recvfrom()函数将返回写入消息的长度到buffer参数所指向的缓冲区。为基于消息的套接字,如SOCK_RAW、SOCK_DGRAM和SOCK_SEQPACKET,整个消息应在一次操作中读取。如果消息太长以适应所提供的缓冲区,并且MSG_PEEK未在标志中设置参数时,多余的字节将被丢弃。对基于流套接字,如SOCK_STREAM,消息边界将被忽略。在在这种情况下,数据应该尽快返回给用户可用,且不得丢弃任何数据。
分配更大的缓冲区或更改客户端发送更小的数据包
从UDP套接字读取数据报。如果您给它一个小于数据报大小的缓冲区,其余部分将被丢弃。使用从下一个数据报返回的数据进一步读取。UDP不为你做任何数据的连接/分割。
最大数据报大小是64KB(在UDP报头的大小字段是16位),所以你可以发送到这个时间与单个write()
/send()
/sendto()
调用,最有可能导致IP碎片。在接收端,您必须将接收缓冲区大小与您发送的最大大小相匹配。
我不建议发送大的UDP数据包。UDP数据包的数据大小被限制在1300字节左右(考虑到路由器的典型MTU是1500或更少),任何更大的数据都被路由器分片,然后再组装回来。
如果路上任何一个路由器不允许分片,所有的数据包将被丢弃。如果任何片段丢失,整个数据包将被丢弃,即使在许多情况下仍然可以使用其余的数据。
传输更大的块的更好方法是手动将它们分成约1250字节的块,然后在接收器上将它们粘合在一起。请记住,其中一些可能会丢失或到货时出现故障。
- Java 客户端C++服务器数据发送/接收问题
- 使用 Libssh 将文件从服务器复制到客户端:分配文件复制目标路径时出现问题
- 从 tcp 服务器打开 8MP H264 流时出现问题
- C++中从客户端到服务器的数据传输问题
- UDP 客户端到 UDP 服务器的问题,出现 10057 错误
- C++机器人程序(我的私人服务器)出现问题
- Caffe 安装问题,远程服务器,ld 找不到 -<package>
- 服务器未收到UDP数据包,花费数小时试图找出问题所在
- C 多线程TCP服务器问题
- 套接字 TCP 服务器程序问题
- Linux TCP服务器问题C++
- 连接到IRC服务器时出现问题
- 服务器/客户端TCP异步(winsock)//FD_WRITE问题
- 基本服务器/客户端代码出现问题
- 通过套接字发送的图像流-服务器死锁问题
- 使用C++CGI解决服务器错误500时遇到问题
- C++:服务器上的 boost::文件系统问题(区域设置::facet::_S_create_c_locale 名称无效
- omniORB C++服务器,Java 客户机在运行应用程序时出现问题
- 提升 HTTP 服务器问题
- C/ c++ UDP服务器问题