gpt4 book ai didi

c++ - Winsock 接收额外数据

转载 作者:搜寻专家 更新时间:2023-10-31 00:42:38 24 4
gpt4 key购买 nike

我尝试使用 Winsock 创建一个文件下载器,但我意识到如果 Internet 连接速度较慢,客户端会收到一些不需要的数据以及服务器发送的数据。
所以我做了一个简单的测试:
我从服务器发送从 1 到 30000 的数字:

char* buf = (char*)malloc(BUFLEN);          
for( int i = 0;i < 30000;++i ){
ZeroMemory(buf, BUFLEN);
itoa(i+1, buf, 10);
send(current_client, buf, BUFLEN, 0);
}
free(buf);

客户端接收并保存它们:

char *buf = (char*)malloc(DEFAULT_BUFLEN);
ofstream out;
out.open(filename, ios::binary);
for( int i = 0;i < 30000;++i ){
ZeroMemory(buf, DEFAULT_BUFLEN);
recv(ConnectSocket, buf, DEFAULT_BUFLEN, 0);
out.write(buf, DEFAULT_BUFLEN);
out << endl;
}
out.close();
free(buf);

我希望在文件中看到类似的内容:
1
2
3
4
...
30000
但是有一些额外的数据包,包含'/0',被传输并且文件看起来像这样:
1
2
3

4
5

6
...
2600
如果我尝试跳过 '/0' 数据包,来自服务器的数据也会像这样被跳过:
1
2
3
4
5
6
9 <- 缺少 7 和 8
...
2600
我做错了什么?

最佳答案

recv() 告诉您实际收到了多少字节。您忽略了输出整个缓冲区的值,即使它没有完全填满。服务器端也一样——发送的数据多于格式化。

您也没有考虑到 send()recv() 可以发送/接收比您请求的更少的字节。

试试这个:

bool sendraw(SOCKET socket, void *buf, int buflen)
{
unsigned char *p = (unsigned char*) buf;
while (buflen > 0)
{
int sent = send(socket, p, buflen, 0);
if (sent < 1) return false;
p += sent;
buflen -= sent;
}
return true;
}

for( int i = 0; i < 30000;++i )
{
int j = htonl(i+1);
if (!sendraw(current_client, &j, sizeof(int)))
break;
}

.

bool recvraw(SOCKET socket, void *buf, int buflen)
{
unsigned char *p = (unsigned char*) buf;
while (buflen > 0)
{
int received = recv(socket, p, buflen, 0);
if (received < 1) return false;
p += received;
buflen -= received;
}
return true;
}

ofstream out;
out.open(filename, ios::binary);
for( int i = 0; i < 30000;++i )
{
int j;
if (!recvraw(ConnectSocket, &j, sizeof(int)))
break;
out << ntohl(j) << endl;
}
out.close();

关于c++ - Winsock 接收额外数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11764687/

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