我正在编写一个UDP客户端,向服务器发送一个字符串,当服务器回复多个数据包时,程序的行为与我的期望不同。我想通过
process()
逐个处理任何传入的数据包,直到输入缓冲区为空,但我认为与 recv
的阻塞行为有关的问题存在。#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <winsock.h>
using namespace std;
void process(const char *in, int size)
{
fprintf(stdout, "%s\n", in);
}
int main()
{
char quack_addr[] = "127.0.0.1";
unsigned short quack_port = 9091;
WSAData data;
WSAStartup(MAKEWORD(2, 2), &data);
sockaddr_in qserver;
qserver.sin_family = AF_INET;
qserver.sin_addr.s_addr = inet_addr(quack_addr);
qserver.sin_port = htons(quack_port);
SOCKET client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (client <= 0)
{
fprintf(stderr, "Error - Can not create socket.\n");
exit(1);
}
while (true)
{
const int MAX = 1024;
char sbuf[MAX];
char rbuf[MAX];
fprintf(stdout, ": ");
fgets(sbuf, MAX, stdin);
int slen = strlen(sbuf);
int r = sendto(client,sbuf,slen,0,(sockaddr*)&qserver,sizeof(qserver));
// Current code:
// int rlen = recv(client, rbuf, MAX, 0);
// if (rlen > 0)
// {
// rbuf[rlen] = 0;
// process(rbuf, rlen);
// }
// Question starts here:
//
// While there is data in queue do:
// {
// (break if there is no data)
// int rlen = recv(client, rbuf, MAX, 0);
// rbuf[rlen] = 0;
// process(rbuf, rlen);
// }
}
return 0;
}
在调用recv(...)
之前,如何检查缓冲区是否为空?
这种情况发生在以下场景中:
- 用户在客户端程序中输入命令(
cmd1
)。 - 同时,服务器向客户端发送3个数据包(
pkt1
,pkt2
,pkt3
)。 - 在客户端按下
Enter
后,我希望接收到这3个数据包,可能还有与cmd1
相对应的结果,并逐个process()
它们。 - 但是,在第3个阶段按下
Enter
后,我只收到了pkt1
!并且在向服务器发送另一个命令后,我将接收到pkt2
等等...!
我知道我的代码无法处理这个问题,所以我的问题是如何处理它?
注意:我正在使用netcat -L -p 9091 -u
作为UDP服务器。