免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4230 | 回复: 6
打印 上一主题 下一主题

原始套接字接收是多了4个字节,是怎么回事?[ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-09 14:43 |只看该作者 |倒序浏览
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 2048
char buf[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";   

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;
}

论坛徽章:
0
2 [报告]
发表于 2011-09-09 14:44 |只看该作者
/////////////////////////////////////////////////////////////////////
//recv.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 2048
char buf[BUF_SIZE];

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 = recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
                printf("recv data2: %d\n", len);               
                if (len>0) {
                        for(i=0; i<len; i++)
                                printf("%x", buf[i]);
                        printf("\n");
                }
        }
       
        close(sfd);
        return 1;
}

论坛徽章:
0
3 [报告]
发表于 2011-09-09 14:47 |只看该作者
以下是运行结果:




上面两个图,第一个是发送端的是109个字节,下面一个是接收端的113个字节,每次都是多了 42 后面的 ffffff81001 ,这个位置应该是二层数据帧的协议,前面正好是12个字节的 DA 和 SA ,不知道为什么系统自动给我加上了这些,我只是想用原始套接字发送二层数据,发送什么还接收什么就行,不过就算是加了协议也应该是2个字节啊,不知道什么问题?

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
4 [报告]
发表于 2011-09-09 15:14 |只看该作者
回复 1# 52dreamer


    recv的时候,你的buf之前清空了再看看呢?

     while (1) {
               memset(buf,0,sizeof(buf));
                len = recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
                printf("recv data2: %d\n", len);

论坛徽章:
0
5 [报告]
发表于 2011-09-09 15:33 |只看该作者
回复 4# crazyhadoop


   谢谢 crazyhadoop !!

我试过了,还是一样的。数据多在中间,我觉得和 buf 没什么关系。

论坛徽章:
0
6 [报告]
发表于 2011-09-10 08:14 |只看该作者
在线等高手解答

论坛徽章:
0
7 [报告]
发表于 2011-09-10 14:10 |只看该作者
我终于搞明白了是4个字节的vlan信息,81001就是0x81000001,正好4个自己,前面的ffffff不知道什么东西,好像也没关系。

谢谢各位!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP