簡體   English   中英

從套接字讀取和轉換字節C的最快方法

[英]Fastest way of reading from socket and converting bytes C++

我想知道哪種方法是在C++中實現這種算法的最快方法:我有一個通過TCP/IP的數據源,因此我從一個套接字讀取所有數據。 我有一個代表字節流和4個字節的整數。 因此,兩種選擇是:

  1. 讀取所有字節,直到結束為止(將它們保存到非常大的unsigned char數組中),然后將其全部轉換。 Pro:我從套接字讀取了“只有一次”(我知道read()函數會盡可能地讀糊糊,但是可以說這總是會發生)。 缺點:將所有字節保存到數組中,但是用這種方式,我必須付出在數組上循環的費用,因為我在其中保存了字節,從而浪費了內存訪問時間。

  2. 一次讀取4個字節並僅對其進行轉換。 優點:沒有內存訪問,因為我沒有將所有字節保存到一個很大的數組中,而是只保存在一個4字節的小數組中。 缺點:我不得不多次調用read(sockfd,buff,4)

在您的意見和經驗方面,您認為最佳方法是什么?

在現代體系結構上,CPU周期將比網絡帶寬更快。

除非您的“轉換”過程占用大量CPU,否則最好轉換任何輸入的數據,然后再嘗試讀取更多數據。

在大多數情況下,甚至不需要完全使用非阻塞套接字和事件處理設計。 一種簡單的方法-只要將可以讀取的任何內容讀入合理大小的緩沖區(例如64kb),然后將其“轉換”,然后再次讀取,就可以正常工作。 注意-一次不是4個字節,效率非常低-但是使用了64kb之類的大緩沖區,然后轉換讀取的4個字節的字,然后保存所有剩余的1-3個字節以與下一次讀取合並嘗試。

因為如果您只是嘗試立即再次讀取,則很有可能您只是在等待下一個數據包到達。 通過仔細閱讀剛剛讀取的數據,還可以更好地利用該時間。

您確實要確保轉換過程足夠快,以便與傳入數據保持同步。 你不想落后。 因此,如果您的轉換過程很耗時,那么最好使用非阻塞套接字,並在嘗試讀取更多數據之前處理相當小的數據塊,以進行緩沖。

recv()或read()一個socket()緩沖區。

您可以執行以下操作:

#define BUFFER_SIZE 1024

char buffer[BUFFER_SIZE];

while(read(fd, buffer, BUFFER_SIZE - 1) != 0){
        fprintf(stderr, "%s", buffer);
        bzero(buffer, BUFFER_SIZE);
}

send()或write()一個套接字

要發送一整批數據而它無法處理,它將觸發盡可能多的數據,並信任您以后再發送其余數據。

#include <sys/types.h>
#include <sys/socket.h>

int sendall(int s, char *buf, int *len)
{
        int total = 0;        // how many bytes we've sent
        int bytesleft = *len; // how many we have left to send
        int n;

        while(total < *len) {
                n = send(s, buf+total, bytesleft, 0);
                if (n == -1) { break; }
                total += n;
                bytesleft -= n;
        }

        *len = total; // return number actually sent here

        return n==-1?-1:0; // return -1 on failure, 0 on success
}

調用函數

char buf[20] = "Hello World!";
int len;

len = strlen(buf);
if (sendall(s, buf, &len) == -1) {
        perror("sendall");
        printf("We only sent %d bytes because of the error!\n", len);
} 

我有一個代表字節流和4個字節的整數。 因此,兩種選擇是:

  • 讀取所有字節,直到結束為止(將它們保存到一個很大的無符號字符數組中),然后將它們全部轉換。
  • 一次讀取4個字節,然后僅對其進行轉換。

您可以直接在int緩沖區中讀取它們(無需轉換):

int buff[1024];
int result = read(sockfd, buff, sizeof(buff));
// check result

// access the `int`'s directly without conversion
int test = buff[0];

根據字節序,您可能需要使用htonl()ntohl()轉換這些int

在完整下載后,我不會讀所有內容都只是在一個大的緩沖區中開始處理數據,因為處理數據的速度可能快於下載速度。

暫無
暫無

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

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