Marc Romero
Marc Romero

Reputation: 115

Sending large data via socket

I'm sending large data (well… 1Mb) via socket, but I don’t know why the send action is blocking the program and never ends. Small sends runs perfectly and I’m couldn’t found where is the problem here. Can anyone help me, please?

Thank you in advance for any help you can provide.

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;
    }
}

Upvotes: 3

Views: 11969

Answers (3)

RobH
RobH

Reputation: 3338

The send() call blocks until all of the data has been sent or buffered. If the program at the other end of the socket isn't reading and thus there is no flow of data, the write buffer at your end will fill up and send() will block. Chances are that when you tried to send a smaller amount of data it fit into the buffer.

See also this answer.

Upvotes: 2

psteelk
psteelk

Reputation: 1365

Check the buffer size, you can do so by following this answer

How to find the socket buffer size of linux

In my case, the values are

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

You can tweak the values net.core.rmem_max and net.core.wmem_max in /etc/sysctl.conf to increase the socket buffer size and reload with sysctl -p.

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

Upvotes: 2

doron
doron

Reputation: 28892

For TCP, the kernel has a fixed size buffer in which is stores unsent data. The size of this buffer is the current window size of the TCP session. Once this buffer is full any new send will be failed. This is a TCP flow control mechanism which prevents you from trying to send data faster than the receiver can consume the data while at the same time providing an automatic resend for lost data. The default window can be as small as 64K but can grow larger for high latency high bandwidth networks.

What you probably need to do is break the data up into smaller send blocks and then ensure you have a flow-off mechanism for when your send buffer is full.

Upvotes: -1

Related Questions