1,本例子使用一台 PC,有两个网口,OS 为 CENTOS 6.8,然后使用两条网线分别都连接到同一个交换机上,当数据经过交换机时,交换机的数据灯会闪烁,否则就没有数据通过交换机。
2,开始测试,刚开始理所当然的想到的是 TCP Server/TCP Client 模式,建立 socket
- int server_sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_sockaddr; server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(MYPORT); server_sockaddr.sin_addr.s_addr = inet_addr(IP_PORT_0);
- if (bind(server_sockfd, (struct sockaddr * ) & server_sockaddr, sizeof(server_sockaddr)) == -1) { perror("bind"); exit(1);
- }
- if (listen(server_sockfd, QUEUE) == - 1) { perror("listen"); exit(1);
- } char buffer[BUFFER_SIZE]; struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); int conn = accept(server_sockfd, (struct sockaddr * ) & client_addr, & length);
- if (conn < 0) { perror("connect"); exit(1);
- }
- while (1) { memset(buffer, 0, sizeof(buffer)); int len = recv(conn, buffer, sizeof(buffer), 0); send(conn, buffer, len, 0);
- } close(conn); close(server_sockfd);
- return 0;
- }
TCP Client 端同样写相应代码,编译通过,先后执行 server/client 程序,显示都有数据收发成功,但交换机的数据灯没有任何显示,于是明白了,系统默认直接从本地发送接收数据,并没有从网卡端口实际发送出去,因为 TCP 是基于 IP 协议之上,而 IP 协议是肯定走本地内部路由,因此使用 TCP,UDP 等 IP 之上的协议肯定不会成功。
- int init_sock (char index[IFNAMSIZ]) { int fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); struct sockaddr_ll sll; struct ifreq ifr; strncpy(ifr.ifr_name, index , IFNAMSIZ); ioctl(fd, SIOCGIFINDEX, & ifr); bzero( & sll, sizeof(sll)); sll.sll_ifindex = ifr.ifr_ifindex; ioctl(fd, SIOCGIFHWADDR, & ifr); memcpy(sll.sll_addr, ifr.ifr_hwaddr.sa_data, 6); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); bind(fd, (struct sockaddr * ) & sll, sizeof(sll));
- return fd;
- }
使用如上 RAW Socket 初始化后,再发送接收,一切 OK!!!,能够接收到除了 CRC 之外的完整链路层帧,包括 MAC 地址,帧类型字段等,程序发送接收时,交换机的数据灯不停闪烁。
来源: http://www.bubuko.com/infodetail-1865295.html