我正在通过套接字发送大数据(好...... 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;
}
}
答案 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()
将阻塞。有可能当你试图发送少量数据时,它适合缓冲区。
答案 2 :(得分:-1)
对于TCP,内核具有固定大小的缓冲区,其中存储未发送的数据。此缓冲区的大小是TCP会话的当前窗口大小。一旦此缓冲区已满,任何新发送都将失败。这是一种TCP流量控制机制,可以防止您尝试以比接收方消耗数据更快的速度发送数据,同时为丢失的数据提供自动重新发送。默认窗口可以小到64K,但对于高延迟高带宽网络可以增大。
您可能需要做的是将数据分解为较小的发送块,然后确保您的发送缓冲区已满时具有流量机制。