簡體   English   中英

循環讀取Socket?

[英]Reading from Socket in a loop?

我正在 C 中創建服務器/客戶端 TCP。

這個想法是讓服務器發送相對大量的信息。 但是,客戶端的緩沖區大小只有512(我不想增加這個大小),而且很明顯,服務器發送的信息比這個大。 讓我們想象一下 812 字節。

我想要做的是,在客戶端,讀取 512 個字節,在客戶端的控制台上打印它們,然后讀取剩余的字節,並打印它們。

這是應該發生的事情:

1)創建服務器,並阻塞在read()系統調用中(等待客戶端寫東西);

2)創建客戶端,在socket中寫入東西,然后阻塞在read()上,等待服務器響應;

3) 服務器的 read() 調用返回,現在服務器必須發送大量數據,使用以下代碼(在創建新進程之后):

dup2(new_socketfd, STDOUT_FILENO); // Redirect to socket

execlp("/application", "application", NULL); // Application that prints the information to send to the client

讓我們想象一下“應用程序”向套接字打印了 812 個字節的數據。

4) 現在客戶端必須讀取 812 字節,緩沖區大小為 512。這是我的問題。

我該如何解決這個問題? 我想知道是否可以創建一個循環並讀取直到沒有可讀取的內容,512 x 512 字節。 但是一旦沒有什么要讀的,客戶端就會阻塞在 read() 上。

有任何想法嗎?

當 stream 中沒有數據時,recv 將阻塞。 從 stream 中提取的任何數據,從 recv 返回長度。 您可以編寫一個簡單的 function 來提取完整數據,只需使用偏移變量並檢查返回值。

像這樣一個簡單的 function 就可以了。

ssize_t readfull(int descriptor,char* buffer, ssize_t sizetoread){
    ssize_t offset = 0;
    while (offset <sizetoread) {
        ssize_t read = recv(descriptor,buffer+offset,sizetoread-offset,0);
        if(read < 1){
            return offset;
        }
        offset+=read;
    }
    return offset;
}

此外,服務器通常會在數據完成時發送某種 EOF。 服務器可能首先發送要讀取的消息的長度,該長度是 4 個或 8 個字節的恆定大小,然后它發送數據,以便您提前知道要讀取多少。 或者,例如在 HTTP 的情況下,存在內容長度字段以及“\r\n”分隔符。

實際上,沒有辦法知道服務器有多少數據可以發送給你,這是不切實際的。 服務器必須通過某種指標告訴你有多少數據。

由於您自己編寫服務器,因此您可以首先發送一個四字節消息,該消息可以是客戶端應該讀取多少數據的 int 值。

所以你的服務器看起來像這樣:

int sizetosend = arbitrarysize;
send(descriptor,(char*)&sizetosend,sizeof(int),0);

send(descriptor,buffer,sizetosend,0);

然后在您的客戶端,讀取四個字節,然后是緩沖區。

int sizetoread = 0;
ssize_t read = recv(descriptor,(char*)&sizetoread,sizeof(int),0);
if(read < 4)
  return;

//Now just follow the code I posted above

暫無
暫無

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

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