首页 > 解决方案 > 如何以更快的方式读取 TCP 数据包?

问题描述

在这里,我将 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() 来捕获数据包。但这需要一些时间。所以我需要加快速度。

标签: c

解决方案


尝试 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));

推荐阅读