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

3 に答える 3

2

バッファサイズを確認してください。これは、この回答に従って行うことができます

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/

于 2012-10-16T10:54:50.387 に答える
2

send()すべてのデータが送信またはバッファリングされるまで、呼び出しはブロックされます。ソケットのもう一方の端にあるプログラムが読み取っていないため、データの流れがない場合、あなたの端にある書き込みバッファがいっぱいになり、send()ブロックされます。少量のデータを送信しようとすると、バッファに収まる可能性があります。

この回答も参照してください。

于 2012-10-16T10:39:10.403 に答える
-1

TCPの場合、カーネルには固定サイズのバッファーがあり、そこに未送信のデータが格納されます。このバッファのサイズは、TCPセッションの現在のウィンドウサイズです。このバッファがいっぱいになると、新しい送信は失敗します。これはTCPフロー制御メカニズムであり、受信者がデータを消費するよりも速くデータを送信しようとするのを防ぎ、同時に失われたデータの自動再送信を提供します。デフォルトのウィンドウは64Kまで小さくすることができますが、高遅延の高帯域幅ネットワークでは大きくなる可能性があります。

おそらく行う必要があるのは、データをより小さな送信ブロックに分割し、送信バッファーがいっぱいになったときのフローオフメカニズムがあることを確認することです。

于 2012-10-16T10:35:04.817 に答える