通过套接字发送大数据

时间:2012-10-16 10:25:54

标签: c++ linux sockets networking tcp

我正在通过套接字发送大数据(好...... 1Mb),但我不知道为什么发送操作会阻止程序并且永远不会结束。小发送完美,我找不到问题在哪里。有人可以帮帮我吗?

提前感谢您提供的任何帮助。

int liResult = 1;
int liConnection = 0;
int liSenderOption = 1;
struct addrinfo laiSenderAddrInfo;
struct addrinfo *laiResultSenderAddrInfo;

memset(&laiSenderAddrInfo,0,sizeof(laiSenderAddrInfo));
laiSenderAddrInfo.ai_socktype = SOCK_STREAM;
laiSenderAddrInfo.ai_flags = AI_PASSIVE;

liResult = getaddrinfo(_sIp.c_str(), _sPort.c_str(), &laiSenderAddrInfo, &laiResultSenderAddrInfo);

if (liResult > -1)
{
    liConnection = socket(laiResultSenderAddrInfo->ai_family, SOCK_STREAM, laiResultSenderAddrInfo->ai_protocol);
    liResult = liConnection;

    if (liConnection > -1)
    {
        setsockopt(liConnection, SOL_SOCKET, SO_REUSEADDR, &liSenderOption, sizeof(liSenderOption));
        liResult = connect(liConnection, laiResultSenderAddrInfo->ai_addr, laiResultSenderAddrInfo->ai_addrlen);
    }
}

size_t lBufferSize = psText->length();
long lBytesSent = 1;
unsigned long lSummedBytesSent = 0;

while (lSummedBytesSent < lBufferSize and lBytesSent > 0)
{
    lBytesSent = send(liConnection, psText->c_str() + lSummedBytesSent, lBufferSize - lSummedBytesSent, MSG_NOSIGNAL);

    if (lBytesSent > 0)
    {
        lSummedBytesSent += lBytesSent;
    }
}

3 个答案:

答案 0 :(得分:2)

检查缓冲区大小,您可以按照以下答案进行操作

How to find the socket buffer size of linux

就我而言,值是

Minimum = 4096 bytes ~ 4KB
Default = 16384 bytes ~ 16 KB
Maximum = 4022272 bytes ~ 3.835 MB

您可以在net.core.rmem_max中调整值net.core.wmem_max/etc/sysctl.conf以增加套接字缓冲区大小,并使用sysctl -p重新加载。

来源:http://www.runningunix.com/2008/02/increasing-socket-buffer-size-in-linux/

答案 1 :(得分:1)

send()调用阻塞,直到所有数据都已发送或缓冲。如果套接字另一端的程序没有读取,因此没有数据流,则末尾的写缓冲区将填满,send()将阻塞。有可能当你试图发送少量数据时,它适合缓冲区。

另见this answer.

答案 2 :(得分:-1)

对于TCP,内核具有固定大小的缓冲区,其中存储未发送的数据。此缓冲区的大小是TCP会话的当前窗口大小。一旦此缓冲区已满,任何新发送都将失败。这是一种TCP流量控制机制,可以防止您尝试以比接收方消耗数据更快的速度发送数据,同时为丢失的数据提供自动重新发送。默认窗口可以小到64K,但对于高延迟高带宽网络可以增大。

您可能需要做的是将数据分解为较小的发送块,然后确保您的发送缓冲区已满时具有流量机制。