0

我知道 C++ 很长时间了,但是大约一年半前开始将它用于我的目的。我开始在 C++ 上学习网络编程,第一个网络项目是“通过 TCP/IP 在主机之间传输文件”,这听起来很简单,但我一直在发送数据。

我正在尝试发送小于 4KB 的小缓冲区,所以 buffer[4096] 对我来说很好,但我打算扩展它。WSAStartup()、socket()、bind()、listen()、accept() 函数工作正常,它们的值已为服务器和客户端初始化,但我正在处理其他问题,可能是 recv()、send()等我仍然找不到问题的根源。

此外,如果有人给我一个通过 TCP/IP 传输文件的示例,但不是在一个数据包中,我希望文件被分块并分部分发送,或者称为“环模型”,但我不能找不到工作模型;

PS这是我第一次在这里问,请反馈一下所有这些写得如何,这样我就可以写出更多信息以寻求社区帮助,谢谢)

服务器

char* buffer = new char[4096];
ZeroMemory(buffer, sizeof(buffer));
ofstream file("a.txt", ios::binary);
int err = recv(conn, buffer, sizeof(buffer), 0);
file << buffer;
file.close();
if (err == 0)
{
    printf("Client diconnected...\n");
}

printf("Quitting...\n");
delete[] buffer;

客户

ifstream file("a.txt", ios::binary);
file.seekg(0, ios::end);
int size = file.tellg();
file.seekg(0, ios::beg);
char* buffer = new char[size];
file.read(buffer, size);
file.close();

int err = send(client, buffer, size, 0);
if (err == 0)
{
    printf("Disconnecting...\n");
}

printf("Quitting...\n");
delete[] buffer;

客户端的“a.txt”文件是 45 字节,这里是 45 * 'a'

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

这就是我在服务器端得到的,文件大小为 14 字节

aaaaaaaa ’pÈ/
4

4 回答 4

2

在 C++ 中,sizeof(buffer)是指针类型的大小。

您可能想阅读更现代的(如 1998 年之后的)C++。我们std::vector现在有,而且有一个方便的size方法。它将返回4096您的缓冲区。此外,矢量手柄new[]delete[]为您服务。

您获得 8 个“a”的事实表明您是为 x64 构建的。剩下的字节是垃圾;recv您应该检查实际写入了多少字节buffer。你不能假设你得到了你要求的所有字节(无论是 8 还是 4096)。

于 2020-08-18T14:50:39.053 回答
1

我相信这一行中的 sizeof(buffer) -->

int err = recv(conn, buffer, sizeof(buffer), 0);

将返回 sizeof(char*),它在 32 位程序中为 4 个字节,在 64 位程序中为 8 个字节,而不是 4096,因为它不是静态数组,因为您没有将其声明为 char 缓冲区 [4096]。因此,要么将其声明为 char buffer[4096],要么将上述代码转换为

int err = recv(conn, 缓冲区, 4096, 0);

于 2020-08-18T14:54:23.217 回答
1

补充两点:

  • TCP 是一种流式协议(不是“基于消息的”),因此不能保证单个recv()将在单个send().

  • 服务器行file << buffer;假定buffer为零终止。

于 2020-08-18T16:11:35.287 回答
0

MSDN 声明:

如果没有发生错误,recv 返回接收到的字节数, buf 参数指向的缓冲区将包含接收到的数据。如果连接已正常关闭,则返回值为零。

否则,返回 SOCKET_ERROR 的值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv

测试你是否真的读取了 45 个字节并检查是否有错误(WSAGetLastError 函数)

于 2020-08-18T14:52:14.120 回答