![](/img/trans.png)
[英]Best way of reading all available bytes from socket in blocking mode, C++
[英]Fastest way of reading from socket and converting bytes C++
我想知道哪種方法是在C++
中實現這種算法的最快方法:我有一個通過TCP/IP
的數據源,因此我從一個套接字讀取所有數據。 我有一個代表字節流和4個字節的整數。 因此,兩種選擇是:
讀取所有字節,直到結束為止(將它們保存到非常大的unsigned char
數組中),然后將其全部轉換。 Pro:我從套接字讀取了“只有一次”(我知道read()
函數會盡可能地讀糊糊,但是可以說這總是會發生)。 缺點:將所有字節保存到數組中,但是用這種方式,我必須付出在數組上循環的費用,因為我在其中保存了字節,從而浪費了內存訪問時間。
一次讀取4個字節並僅對其進行轉換。 優點:沒有內存訪問,因為我沒有將所有字節保存到一個很大的數組中,而是只保存在一個4字節的小數組中。 缺點:我不得不多次調用read(sockfd,buff,4)
。
在您的意見和經驗方面,您認為最佳方法是什么?
在現代體系結構上,CPU周期將比網絡帶寬更快。
除非您的“轉換”過程占用大量CPU,否則最好轉換任何輸入的數據,然后再嘗試讀取更多數據。
在大多數情況下,甚至不需要完全使用非阻塞套接字和事件處理設計。 一種簡單的方法-只要將可以讀取的任何內容讀入合理大小的緩沖區(例如64kb),然后將其“轉換”,然后再次讀取,就可以正常工作。 注意-一次不是4個字節,效率非常低-但是使用了64kb之類的大緩沖區,然后轉換讀取的4個字節的字,然后保存所有剩余的1-3個字節以與下一次讀取合並嘗試。
因為如果您只是嘗試立即再次讀取,則很有可能您只是在等待下一個數據包到達。 通過仔細閱讀剛剛讀取的數據,還可以更好地利用該時間。
您確實要確保轉換過程足夠快,以便與傳入數據保持同步。 你不想落后。 因此,如果您的轉換過程很耗時,那么最好使用非阻塞套接字,並在嘗試讀取更多數據之前處理相當小的數據塊,以進行緩沖。
您可以執行以下操作:
#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];
while(read(fd, buffer, BUFFER_SIZE - 1) != 0){
fprintf(stderr, "%s", buffer);
bzero(buffer, BUFFER_SIZE);
}
要發送一整批數據而它無法處理,它將觸發盡可能多的數據,並信任您以后再發送其余數據。
#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.