C++ 使用套接字一次性发送整个数据
我正在尝试使用C++ 使用套接字一次性发送整个数据,c++,sockets,winsock,winsock2,C++,Sockets,Winsock,Winsock2,我正在尝试使用winsock2lib将文件从客户端发送到服务器 将文件转换为char数组后,我将使用send()命令发送此数组 问题:单独发送的数据 例如:我有大小为144429的文件。 它不会立即发送数据,数据被分成许多部分,如: 首次发送:1460 第二次发送:21544 第三次发送:57136 等等 直到发送到整个数据 所以我的问题是:是什么导致它以部分而不是一次的方式发送 我发现解决方案可行,但毫无意义: 如果我加上 cout根据您使用的套接字类型,底层传输协议中可能存在数据大小限制 如
winsock2
lib将文件从客户端发送到服务器
将文件转换为char数组后,我将使用send()
命令发送此数组
问题:单独发送的数据
例如:我有大小为144429的文件。
它不会立即发送数据,数据被分成许多部分,如:
首次发送:1460
第二次发送:21544
第三次发送:57136
等等
直到发送到整个数据
所以我的问题是:是什么导致它以部分而不是一次的方式发送
我发现解决方案可行,但毫无意义:
如果我加上
cout根据您使用的套接字类型,底层传输协议中可能存在数据大小限制 如果您使用的是网络套接字,则其大小受最大传输单位的限制(请参阅:)
如果数据不适合此大小,则必须在循环中迭代发送部分数据,直到发生错误或发送所有数据。根据您使用的套接字类型,底层传输协议中可能存在数据大小限制 如果您使用的是网络套接字,则其大小受最大传输单位的限制(请参阅:)
如果您的数据不适合此大小,您将不得不在循环中迭代发送部分数据,直到出现错误或所有数据都已发送。无法保证
send
将一些数据作为一个单元进行传输-它就是不起作用。您必须添加一些额外的信息来告诉系统“有这么多数据要来”和/或“我现在完成了”。即使你能说服你的发送端在一个数据包中发送所有信息,假设接收端没有直接用一根简单的电缆连接到发送方,你也不能保证数据包在通过网络的过程中没有被破坏
您只需要接受这样一个事实:如果您在一个数据包中发送的数据超过一个字节,那么您可能需要多次调用send。为了简化它,编写一个函数,它接受任意大小的“整包”,并根据需要多次调用send。。。如果您有一个协议指示发送的数据的大小[比如前几个字节],那么您可以有一个接收函数来执行相同的操作 无法保证
send
将一些数据作为一个单元进行传输-它就是不能这样工作。您必须添加一些额外的信息来告诉系统“有这么多数据要来”和/或“我现在完成了”。即使你能说服你的发送端在一个数据包中发送所有信息,假设接收端没有直接用一根简单的电缆连接到发送方,你也不能保证数据包在通过网络的过程中没有被破坏
您只需要接受这样一个事实:如果您在一个数据包中发送的数据超过一个字节,那么您可能需要多次调用send。为了简化它,编写一个函数,它接受任意大小的“整包”,并根据需要多次调用send。。。如果您有一个协议指示发送的数据的大小[比如前几个字节],那么您可以有一个接收函数来执行相同的操作重定位到C++。是的,一些代码就可以了。sendbufnull是否终止?换言之,指针是否指向int C++中的范围内的数据的大小::sDeDATA()?@凯文:是的,大小是已知的,并给出一个参数——int长度。是的,一些代码就可以了。sendbufnull是否终止?换句话说,指针指向的数据的大小是否在int Client::sendData()的范围内已知?@Kevin是的,该大小已知并作为参数给定-int length。我知道总有一个限制,但在这种情况下,我已经通过一个初步的send命令成功地立即发送数据,并在随后执行cout(为什么有效?我不知道..)我知道总有一个限制,但在这种情况下,我已经通过一个初步的send命令立即成功地发送了数据,之后又失败了(为什么有效?我不知道..)+1,是的-不断重复出现的“我想通过流式服务发送大于一个字节的消息”。+1这也意味着最初读取整个文件而不是字节数组的努力是浪费时间和空间。只需使用合理大小的缓冲区读取和写入缓冲区,直到流结束。你可以看到缓冲区超过了4-8k也是毫无意义的。+1,是-不断重复的“我想通过流媒体服务发送大于一个字节的消息”。+1这也意味着最初读取整个文件而不是字节数组的努力是浪费时间和空间。只需使用合理大小的缓冲区,读写缓冲区加载到流结束。您可以看到超过4-8k的速度也毫无意义。
int Client::sendData(char *sendbuf, int length)
{
int iResult;
// if I remove those next few lines (until and including the cout line)
// the send will split.
char tmp[1];
// sent 1 dummy byte
iResult = send( _connectSocket, tmp, 1, 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
return closeSocket();
}
cout << "SENDING DATA..." << endl;
// THIS IS THE RELEVANT AND ACTUAL DATA I WANT TO SEND
// send the data
iResult = send( _connectSocket, sendbuf, length, 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
return closeSocket();
}
cout << "Data sent (" << iResult << " Bytes)" << endl;
return 0;
}
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int iResult = 0;
int totalBytesRead = 0;
// Receive until the peer shuts down the connection
do {
totalBytesRead += iResult;
iResult = recv(_clientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("RECEIVED DATA\n");
printf("Bytes received: %d\n", iResult);
} else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed: %d\n", WSAGetLastError());
closesocket(_clientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
// store data into file
FileTransfer::binaryToFile(recvbuf, "doch.docx", totalBytesRead-1);
return 0;