gpt4 book ai didi

c++ - C/C++ UDP 服务器问题

转载 作者:太空宇宙 更新时间:2023-11-04 06:07:34 24 4
gpt4 key购买 nike

我这里有一个在端口 9001 上监听的 UDP 服务器。我已经为接收数据缓冲区定义了最大块大小为 4096。

我的问题是,当客户端发送大量数据时,例如。 20000 字节,我只收到了我定义的 block 大小。我有一个无限循环,它将不断从客户端接收数据。

这是我的代码:

  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.NET 编写

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() 的工作原理

The recvfrom() function shall return the length of the message written to the buffer pointed to by the buffer argument. For message-based sockets, such as SOCK_RAW, SOCK_DGRAM, and SOCK_SEQPACKET, the entire message shall be read in a single operation. If a message is too long to fit in the supplied buffer, and MSG_PEEK is not set in the flags argument, the excess bytes shall be discarded. For stream-based sockets, such as SOCK_STREAM, message boundaries shall be ignored. In this case, data shall be returned to the user as soon as it becomes available, and no data shall be discarded.

分配更大的缓冲区或更改客户端以发送更小的数据包

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

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com