我建议您重新检查是否真的有必要以您描述的方式拦截数据包。如上所述,您似乎还没有完全理解网络的工作原理。
首先,除非您的程序以某种方式神奇地设法读取原始网络数据包而不是使用标准套接字,否则它们无论如何都不会接收到彼此注定的流量。每个套接字都有一个与之关联的端口,并且只有一个进程可以绑定到同一主机中的同一端口(套接字实际上只不过是一对端口和一个主机地址)。
如果您实际上是在程序中读取原始网络数据包并且这是必要的,那么您很可能不应该在同一主机上运行它们。而是使用虚拟化将不允许看到发往彼此的数据包的程序放在不同的虚拟主机中,从而将它们完全分开,而不是使用相当复杂的编程解决方案。
如果一切都失败了,您可能需要仔细查看libpcap,它允许您捕获网络数据包,甚至同时来自多个程序。尽管您必须以 root 身份运行它们,但无论如何这对于能够将网络接口置于混杂模式等等都是必要的。这是一个从网络上读取一些东西的简单示例,您可以从 libpcap 主页和相关的
中找到更多
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
/* IP header (from tcpdump examples) */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
/* callback function for pcap_loop */
void cllbck(u_char * args,
const struct pcap_pkthdr *hdr, const u_char * pkt)
{
const struct sniff_ip *ip = (struct sniff_ip *) (pkt + 14);
fprintf(stderr, "Sniffed a packet with length %d.\n", hdr->len);
fprintf(stderr, "IP version %d.\n", ip->ip_vhl >> 4);
}
int main(int argc, char *argv[])
{
char *dev; /* device name */
char errbuf[PCAP_ERRBUF_SIZE]; /* buffer for libpcap errmsgs */
pcap_t *cap; /* libpcap capture session */
char *filt = "host 127.0.0.1"; /* capture filter */
struct bpf_program fp; /* compiled filter */
struct pcap_pkthdr hdr; /* packet header from libpcap */
const u_char *pkt; /* packet from libpcap */
dev = strdup(argv[1]);
if (dev == NULL) {
fprintf(stderr, "Invalid device.\n");
return 2;
}
/* open the device for live capture */
cap = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (cap == NULL) {
fprintf(stderr, "Opening device `%s´ failed: %s\n", dev, errbuf);
return 2;
}
/* compile the capture filter */
if (pcap_compile(cap, &fp, filt, 0, PCAP_NETMASK_UNKNOWN) < 0) {
fprintf(stderr, "Failed to parse filter `%s´: %s\n",
filt, pcap_geterr(cap));
return 2;
}
/* set the filter active for this session */
if (pcap_setfilter(cap, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n",
filt, pcap_geterr(cap));
return 2;
}
/* pcap close will loop until an error if 2nd arg is < 0 */
pcap_loop(cap, -1, cllbck, NULL);
/* end session, pcap_loop has exited ie. an error has occurred */
pcap_close(cap);
return 0;
}
/* end of file */