簡體   English   中英

從Unix本地套接字接收和緩沖區大小

[英]receive from unix local socket and buffer size

我在使用Unix本地套接字時遇到問題。 在讀取長度超過我的臨時緩沖區大小的消息時,請求花費的時間太長(可能無限期)。

經過一些測試后添加 ::: recv處的凍結仍然存在問題。 當我向UNIX套接字發送(1023 * 8)個字節或更少的字節時-一切正常,但是當發送大於(1023 * 9)個字節時-我在recv命令中凍結。 也許它的FreeBSD默認UNIX套接字限制或C ++默認套接字設置? 誰知道?


我進行了一些附加測試,當嘗試讀取長度大於等於(1023 * 9)字節的消息時,我100%確信在執行:: recv命令時,它在最后第9次“凍結”。 (第8次發送信號良好)。

我在做什么:的想法是從一個套接字讀取do / while循環

::recv (current_socket, buf, 1024, 0);

並檢查buf是否有特殊符號。 如果找不到:

  1. 將緩沖區的內容合並到stringxxx += buf;
  2. bzero臨時buf
  3. 繼續:: recv循環

如何解決while循環中的請求時間過長的問題?

有更好的方法清除緩沖區嗎? 當前是:

 char buf [1025];
 bzero(buf, 1025);

但是我知道在新的c ++標准中不贊成使用bzero。

編輯: * “為什么需要清理緩沖區 *

我在有關此問題的評論中看到了問題。 如果不對下一次(最后一次)讀取緩沖區進行緩沖區清除,它將包含消息第一部分的“尾部”。

例:

 // message at the socket is "AAAAAACDE"
 char buf [6];
 ::recv (current_socket, buf, 6, 0); // read 6 symbols, buf = "AAAAAA"
 // no cleanup, read the last part of the message with recv
 ::recv (current_socket, buf, 6, 0); 
 // read 6 symbols, but buffer contain only 3 not readed before symbols, therefore
 // buf now contain "CDEAAA" (not correct, we waiting for CDE only)

除了bzero ,您可以使用

memset(buf, 0, 1025);

這些是2個獨立的問題。 時間長了可能是由於代碼中的錯誤導致的無限循環,與清除緩沖區的方式無關。 事實上,您不必清除緩沖區; receive返回讀取的字節數,因此您可以在此之前掃描緩沖區中的SPECIAL_SYMBOL。

如果您粘貼代碼,也許我可以幫助您。 更多。

需要澄清的是: bzero在C ++ 11中並未被棄用。相反,它從未成為任何 C或C ++標准的一部分。 C始於20年前的memset 對於C ++,您可以考慮使用std::fill_n代替(或僅使用std::vector ,它可以自動零填充)。 再說一次,我不確定在這種情況下是否有充分理由將緩沖區零填充。

當您的recv()進入無限循環時,這可能意味着它在迭代上沒有任何進展(即,您始終會立即讀取零大小的簡短內容,因此您的循環永遠不會退出,因為您沒有獲取任何數據)。 對於流套接字,大小為recv()的零表示遠程端已斷開連接(這類似於將輸入置於EOF時也從文件read()也會使您得到零字節),或者至少它已關閉向下發送通道(專門用於TCP)。

檢查您的PHP腳本是否實際發送了聲稱已發送的數據量。

要添加一個小的(荒謬的)示例以在循環中正確使用recv():

char buf[1024];
std::string data;
while( data.size() < 10000 ) { // what you wish to receive
    ::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0);
    if( rcvd < 0 ) {
        std::cout << "Failed to receive\n";  // Receive failed - something broke, see errno.
        std::abort();
    } else if( !rcvd ) {
        break; // No data to receive, remote end closed connection, so quit.
    } else {
        data.append(buf, rcvd); // Received into buffer, attach to data buffer.
    }
}

if( data.size() < 10000 ) {
    std::cout << "Short receive, sender broken\n";
    std::abort();
}

// Do something with the buffer data.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM