从套接字读取和转换字节C ++的最快方法

时间:2016-01-10 02:32:52

标签: c++ performance sockets tcp-ip

我想知道哪种是C++中实现此类算法的最快方法: 我有一个来自TCP/IP的数据源,所以我从单个套接字读取所有数据。我有一个表示4字节整数的字节流。所以两种选择是:

  1. 读取所有字节直到结束(将它们保存到一个非常大的unsigned char数组中),然后将它们全部转换。专业版:我从套接字中读取“只有一个”时间(我知道read()函数尽可能读取,但可以说这总是发生)。缺点:将所有字节保存到数组中但是这样我必须支付循环数组的成本,在那里我保存了字节,减少了内存访问的时间。

  2. 一次读取4个字节并仅转换它们。 Pro:没有内存访问,因为我没有将所有字节保存到一个非常大的数组中,而只是在一个4字节的小数组中。缺点:我必须多次致电read(sockfd,buff,4)

  3. 您认为对您的观点和经验表现最好的方式是什么?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

在现代架构中,CPU周期将比网络带宽更快。

除非你的转换&#34;进程非常耗费CPU,在尝试阅读更多内容之前,转换所有数据会更好。

在大多数情况下,甚至可能没有必要使用非阻塞套接字和事件处理设计进行全油门。一个简单的方法 - 只需读取任何可以读入合理大小的缓冲区,比如64kb,&#34;转换&#34;它,然后再读一遍 - 应该运作良好。注意 - 一次不是4个字节,这非常低效 - 但是使用像64kb这样的大缓冲区,然后转换多个读取的4字节字,然后保存剩余的1-3个字节进行合并下次读取尝试。

因为如果您只是尝试再次阅读,那么您很可能只是等待下一个数据包到达。也可以通过咀嚼刚刚读取的数据来更好地利用那段时间。

您确实希望确保转换过程足够快,以便与传入的数据保持同步。你不想落后。因此,如果您的转换过程可能非常耗时,那么最好使用非阻塞套接字,并在尝试读取更多数据之前处理相当小的数据块,以便提前缓冲。

答案 2 :(得分:0)

  

我有一个表示4字节整数的字节流。所以   两种选择是:

     
      
  • 读取所有字节直到结束(将它们保存到一个非常大的数组中)   unsigned char)然后将它们全部转换。
  •   
  • 一次读取4个字节并仅转换它们。
  •   

您可以直接在int buff[1024]; int result = read(sockfd, buff, sizeof(buff)); // check result // access the `int`'s directly without conversion int test = buff[0]; 的缓冲区中阅读它们(无需转换):

int

根据字节顺序,您可能需要将这些htonl()转换为ntohl()$iterator = 1; while($results = $stmt->fetch(PDO::FETCH_ASSOC) and $iterator == 1){ /* I need just first row here */ print_r($results); $iterator++; } while($results = $stmt->fetch(PDO::FETCH_ASSOC)){ /* I need other rows here */ print_r($results); }

我不会在一个大缓冲区中读取所有内容,只是在完全下载后开始处理数据,因为处理数据的速度可能比下载速度快。