问题描述
我很早就了解C ++,但是大约一年半以前,出于我的目的开始使用它。 我开始学习C ++上的网络编程,并且第一个网络项目是“通过TCP / IP在主机之间进行文件传输”,这听起来很简单,但是我一直在发送数据。
我正在尝试发送小于4KB的小缓冲区,因此buffer [4096]对我来说很好用,但我打算对此进行扩展。 WSAStartup(),socket(),bind(),listen(),accept()函数可以正常工作,并且为服务器和客户端初始化了它们的值,但是我正在处理其他问题,也许是recv(),send()等等 我仍然找不到问题的根源。
如果有人给我一个通过TCP / IP传输文件的示例,但不是以一个数据包的形式进行传输,那我将大有帮助,我希望文件被分块并分批发送,也称为“环形模型”,但我找不到可行的模型;
P.S。这是我第一次在这里问问题,请提供有关所有这些内容编写情况的反馈,以便我可以写出更多有关社区帮助的信息,谢谢)
服务器
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,size,0);
if (err == 0)
{
printf("disconnecting...\n");
}
printf("Quitting...\n");
delete[] buffer;
客户端上的“ a.txt”文件为45个字节,此处为45 *'a'
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
这就是我在服务器端得到的文件大小为14字节
aaaaaaaa ’pÈ/
解决方法
在C ++中,sizeof(buffer)
是指针类型的大小。
您可能想阅读更现代的(例如1998年以后)的C ++。如今,我们有std::vector
,并且有一个方便的size
方法。它将为您的缓冲区返回4096
。另外,vector为您处理new[]
和delete[]
。
您得到8个“ a”的事实表明您是为x64构建的。剩下的字节是垃圾。您应该检查recv
实际写入了buffer
的字节数。您不能假设您已经获得了所有要求的字节(无论是8还是4096)。
我相信这一行的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,buffer,4096,0);
,另外两点:
-
TCP是一种流协议(不是“基于消息的”),因此不能保证单个
recv()
会在单个send()
中发送所有内容。 -
服务器行
file << buffer;
假定buffer
被零终止。
MSDN指出:
如果未发生错误,则 recv返回收到的字节数和 buf参数指向的缓冲区将包含此数据 收到。如果连接已正常关闭,则返回 值为零。
否则,将返回SOCKET_ERROR的值,并返回特定错误 可以通过调用WSAGetLastError来检索代码。
https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv
测试您是否实际读取了45个字节并检查是否存在错误(WSAGetLastError函数)