使用套接字一次性发送全部数据



我正在尝试使用winsock2 lib从客户端发送文件到服务器。

将文件转换为字符数组后,我使用send()命令发送此数组。

问题:数据单独发送。

例如:我有一个大小为144429的文件。它不会立即发送数据,而是将数据分成许多部分,比如:第一次发送:1460

second send: 21544

第三次发送:57136

等。

直到全部数据发送完毕。

所以我的问题是:是什么导致它发送它的部分,而不是一次????

解决方案,我发现工作,但没有任何意义:如果我添加

cout & lt; & lt;

在send()函数之前,它确实工作并将整个144429发送一次。(但如果给cout的字符串较短,则不更改,按部分发送)

代码:

客户端

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: %dn", 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: %dn", 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 DATAn");
        printf("Bytes received: %dn", iResult);
    } else if (iResult == 0)
        printf("Connection closing...n");
    else {
        printf("recv failed: %dn", WSAGetLastError());
        closesocket(_clientSocket);
        WSACleanup();
        return 1;
    }
} while (iResult > 0);
// store data into file
FileTransfer::binaryToFile(recvbuf, "doch.docx", totalBytesRead-1);
return 0;

}

没有办法保证send传输一些数据作为一个单位-它只是不工作的方式。你必须添加一些额外的信息来告诉系统"这里有这么多数据"和/或"我现在完成了"。即使你能说服你的发送方在一个数据包中发送所有的东西,假设接收方没有直接与发送方连接,你也不能保证数据包在通过网络时不会被破坏。

你只需要接受,如果你在一个数据包中发送多个字节,你可能不得不多次调用send。为了简化它,编写一个函数,它接受一个任意大小的"整个数据包",并根据需要多次调用send…如果你有一个指示发送数据大小的协议[比如在前几个字节],你可以有一个做同样事情的接收函数。

根据您使用的套接字类型,底层传输协议中可能存在数据大小限制。

如果您使用的是网络套接字,则大小受最大传输单元的限制(参见:http://en.wikipedia.org/wiki/Maximum_transmission_unit)。

如果你的数据不适合这个大小,你将不得不在循环中迭代发送部分数据,直到发生错误或所有数据都已发送。

最新更新