如何更快地读取TCP数据包?

时间:2018-11-07 05:24:18

标签: c

在这里,我将TCP数据包发送到了环回接口。同时,我尝试使用pcap库从该接口捕获那些数据包。但是这种捕获花费了一些时间,并导致整个过程变慢。因此,我需要找出一种快速读取TCP数据包的方法。(代码为c语言)

while (1) {
    u_int max_len = 1514 - sizeof (packet_hdr);
    if (max_len < (tot_len - data_send))len = max_len;
    else len = tot_len - data_send;

    packet = finalize(packet_hdr, arr, len, tmp_len, src_port, src_ip, dst_port, dsts_ip, eth_src, eth_dst);  //initialize TCP header fields.

    u_char *buff_cpy = (u_char*) malloc(sizeof (packet));
    memcpy(buff_cpy, (const u_char*) &packet, sizeof (packet));

    int send = pcap_sendpacket(conn_handler, buff_cpy, sizeof (packet_hdr) + packet.len);  //send TCP packets into loopback interface.

    free(buff_cpy);
    packet1 = pcap_next(conn_handler, &packet_header);  //capture sent packets into loopback interface
    printf("capture: %d\n", packet_header.caplen);

    if (send == -1) printf("PACKET NOT SEND");
    data_send += packet.len;
    if (data_send == tot_len) break;
}

这是我的代码的一部分,并使用pcap_next()捕获数据包。但这花了一些时间,所以我需要加快速度。

1 个答案:

答案 0 :(得分:1)

尝试使用RAW套接字和recvfrom()。它应该很快。示例:

int fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if (fd != -1)
{
    char buf[2345];
    struct sockaddr_in addr;

    for (int i = 0; i < 10; i++)
    {
        socklen_t addrlen = sizeof(addr);
        int len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addrlen);
        printf("len = %d\n", len);
    }
    close(fd);
}

示例代码接收所有带有IP标头的传入TCP数据包。 如果需要,可以将其绑定到回送接口。 您必须自己实施其他过滤。

用于绑定到回送接口:

struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "lo", sizeof(ifr.ifr_name));
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));