2012-10-16 50 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.