通过插座发送大数据
Sending large data via socket
我正在通过套接字发送大数据(好…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;
}
}
检查缓冲区的大小,您可以按照此答案
来做到这一点如何找到Linux的套接字缓冲区
在我的情况下,值为
Minimum = 4096 bytes ~ 4KB
Default = 16384 bytes ~ 16 KB
Maximum = 4022272 bytes ~ 3.835 MB
您可以在/etc/sysctl.conf
中调整net.core.rmem_max
和net.core.wmem_max
的值,以增加套接字缓冲区大小,并使用sysctl -p
重新加载。
来源:http://www.runningunix.com/2008/02/increasing-socket-buffer-size-in-linux/
send()
调用块,直到发送或缓冲所有数据为止。如果插座另一端的程序未读取,因此没有数据流,则末端的写缓冲区将填充,send()
将阻止。当您尝试将其适合缓冲区的较小数据发送时,很有可能。
另请参阅此答案。
对于TCP,内核具有固定的尺寸缓冲区,其中存储了未输入的数据。此缓冲区的大小是TCP会话的当前窗口大小。一旦此缓冲区已满,任何新的发送将失败。这是一种TCP流量控制机制,它阻止您尝试比接收方更快地发送数据的速度可以消耗数据,同时为丢失的数据提供自动重新启动。默认窗口可能小于64K,但对于高潜伏期高带宽网络可能会增长。
您可能需要做的是将数据分解为较小的发送块,然后确保您在发送缓冲区已满时具有流动机制。
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- TOS字段从Linux的TCP插座上接收到的数据包获取
- 插座无法接收数据?客户使用boost.asyio库编写.服务器用Python编写
- 发送和接收所有数据(C 插座)
- 插座 - 数据传输后保持插座打开
- 如何通过CPP中的插座流式数据图
- 通过插座发送的内容的数据类型是什么
- C 插座未接收传入的数据包,在Python中工作
- C 通过插座发送数据包
- 使用UDP插座(C )错误接收数据
- Python插座未从C Boost ASIO接收所有数据
- 关于发送/接收大量数据(UNIX-)插座的另一种融合
- 从SFML插座接收数据时随机输出
- TCP插座即使在执行sendall()后也无法发送数据
- 插座上的数据包大小修改
- UDP插座(多播)未接收数据(Ubuntu)
- 通过插座发送大数据