首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

原始套接字接收是多了4个字节,是咋回事

2012-03-17 
原始套接字接收是多了4个字节,是怎么回事?rt 两个一样的开发板,一个发送,一个接收,不管哪边发哪边接,接收

原始套接字接收是多了4个字节,是怎么回事?
rt 两个一样的开发板,一个发送,一个接收,不管哪边发哪边接,接收方都会多四个字节,正好多在二层数据帧协议出,不知道如何解决,以下是源代码:

C/C++ code
//send.c#include <stdio.h>#include <stdlib.h>        //perror#include <string.h>        //strcpy,memset#include <sys/socket.h>        //socket#include <sys/ioctl.h>        //ioctl#include <net/if.h>        //ifreq#include <linux/if_packet.h>    //sockaddr_sll#include <linux/if_ether.h>        //ETH_P_ALL#define IFRNAME0 "eth0"#define IFRNAME2 "eth2"#define BUF_SIZE 2048char buf[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";    int main(int argc, char *argv[]){    int i, sfd, len;    struct sockaddr_ll sll;    struct ifreq ifr;        if ((sfd=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {        perror("socket");        return 0;    }        memset(&ifr, 0, sizeof(ifr));    strcpy(ifr.ifr_name, IFRNAME0);    if ((ioctl(sfd, SIOCGIFINDEX, &ifr)) == -1) {        strcpy(ifr.ifr_name, IFRNAME2);        if ((ioctl(sfd, SIOCGIFINDEX, &ifr)) == -1) {                        perror("ioctl 1");            close(sfd);            return 0;        }    }            memset(&sll, 0, sizeof(sll));        sll.sll_family = PF_PACKET;    sll.sll_ifindex =  ifr.ifr_ifindex;    sll.sll_protocol = htons(ETH_P_ALL);    if ((bind(sfd, (struct sockaddr *)&sll, sizeof(sll))) == -1) {        perror("bind");        close(sfd);        return 0;    }    while (1) {        len = sizeof(buf);        sendto(sfd, buf, len, 0, (struct sockaddr *)&sll, sizeof(sll));        printf("send data2: %d\n", len);        for(i=0; i<len; i++)            printf("%x", buf[i]);        printf("\n");    }    close(sfd);    return 1;}



[解决办法]
你别往板子上发,往PC机上发数据,用wireshark抓数据包看看,
[解决办法]
这样看来,就是你板子上的网络接收造成的了。。。
你板子的操作系统是linux吗?linux下UDP接收,一般不是你这么写的呀!
C/C++ code
 sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); tsRevSockPara.sin_family = AF_INET; tsRevSockPara.sin_port = htons(port); tsRevSockPara[i].sin_addr.s_addr = htonl(INADDR_ANY); bind(sockfd, (struct sockaddr*)&tsRevSockPara, sizeof(tsRevSockPara));
[解决办法]
是数据链路层的4字节CRC, 
C R C字段用于帧内后续字节差错的循环冗余码检验(检验和)(它也被称为F C S或帧检验
序列)。
8 0 2 . 3标准定义的帧和以太网的帧都有最小长度要求。8 0 2 . 3规定数据部分必须至少为3 8字
节,而对于以太网,则要求最少要有4 6字节。为了保证这一点,必须在不足的空间插入填充
(p a d)字节
[解决办法]


原始套接字工作在网络层。可以直接取得原始数据,发送的时候没看见你定义任何头部,没看见你的效验和计算,没看见你接受的时候做任务协议的解包过程!
[解决办法]
探讨

是数据链路层的4字节CRC,
C R C字段用于帧内后续字节差错的循环冗余码检验(检验和)(它也被称为F C S或帧检验
序列)。
8 0 2 . 3标准定义的帧和以太网的帧都有最小长度要求。8 0 2 . 3规定数据部分必须至少为3 8字
节,而对于以太网,则要求最少要有4 6字节。为了保证这一点,必须在不足的空间插入填充
(p a d)字节

[解决办法]
探讨
谢谢以上各位,其实是四个字节的 VLAN 标签 0x81000001,vid 为1,至于为什么加上了这个标签,我还不清楚,还有前面的 ffffff 我也没搞明白到底怎么回事。

[解决办法]
不是TCP协议的问题了,很多奇怪的事都是上层的程序出问题了.本人经常遇这种问题.如(加个printf打印值就变了,而且是很奇怪变了,套接字接收时分2次接收);
你接收的这端这样改下.这段注释吧,我不知道你这程序是用来作什么的,是查看网卡的数据,还是只为发送数据,如果是只发数据根本用不到这原始套接字,如果是想对底层协议解包重组,但也没看到你定协议包.


/*memset(&sll, 0, sizeof(sll));

sll.sll_family = PF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);

if ((bind(sfd, (struct sockaddr *)&sll, sizeof(sll))) == -1) {
perror("bind");
close(sfd);
return 0;
}*/
[解决办法]
那些支持vlan的交换机,给你加上去vlantag的吧, IEEE 802协议什么的有几个,有的这个头部就是带vlan的。这个的看 协议了。 

你其实可以自己过滤掉这个4个字节啊! 

你这开发板是linux 平台的? 可以看看linux的vlan支持能不能关掉,网卡驱动的代码是怎么作的

热点排行