2012-10-16 51 views
3

我正在通过套接字发送大量数据(以及... 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; 
    } 
} 

回答

-1

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

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

+0

OP没有失败;他是封锁的:显然他并不处于非封锁模式,我希望你说'失败'(EAGAIN/EWOULDBLOCK)时指的是你所指的。默认的TCP窗口可能比64k小很多:例如在Windows上尝试8k;除非你分别在调用'accept()'和'connect()'之前采取特殊措施,否则它不能增长到64k-1以上。将数据分成更小的发送块将对这个问题产生零影响。 Downvote。 – EJP

1

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

又见this answer.