• Linux-UDP-Socket编程


    接收CAN总线上的数据并将其发送出去

    创建客户端:

    /********************************************************************
    *       copyright (C) 2018 all rights reserved
    *            @file: server.c
    *         @Created: 2018-4-16 13:22nd 
    *          @Author: Yinrui Zhu
    *     @Description: test user eth0 
    *     @Modify Date: 2018-4-13
    *********************************************************************/
    
    #include <limits.h>
    #include <stdint.h>
    #include <getopt.h>
    #include <libgen.h>
    #include <signal.h>
    #include <net/if.h>
    #include <sys/ioctl.h>
    #include <linux/can.h>
    #include <linux/can/raw.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <pthread.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    #define SERVER_PORT 8000
    #define BUFFER_SIZE 1024
    #define ipaddr "192.168.200.110"
    #define FILE_NAME_MAX_SIZE 512
    
    int main()
    {
        int nbytes,i,addrlen;
        char abuf[12];
        char bbuf[12];
        char cbuf[12];
        char dbuf[12];
        char ebuf[12];
        
        int s;
        struct sockaddr_can addr;
        struct ifreq ifr;
        struct can_frame frame;
        struct can_filter rfilter[5];
        int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW;
        
        system("ip link set can0 type can bitrate 125000 triple-sampling on");
        sleep(2);
        system("ip link set can0 up");
        
        s = socket(family, type, proto);                                            //创建套接字
        
        strcpy(ifr.ifr_name, "can0");
        ioctl(s, SIOCGIFINDEX,&ifr);                                                //指定can0设备
        
        addr.can_family = family;
        //addr.can_family = AF_CAN;
        addr.can_ifindex = ifr.ifr_ifindex;
        bind( s, (struct sockaddr *)&addr, sizeof(addr) );                            //将套接字与can0设备绑定
        
        /*定义接收规则*/
        rfilter[0].can_id = 0x10;                                                    //接收ID为0x10的报文
        rfilter[0].can_mask = CAN_SFF_MASK;
        
        rfilter[1].can_id = 0x20;                                                    //接收ID为0x20的报文
        rfilter[1].can_mask = CAN_SFF_MASK;
        
        rfilter[2].can_id = 0x40;                                                    //接收ID为0x40的报文
        rfilter[2].can_mask = CAN_SFF_MASK;
        
        rfilter[3].can_id = 0x80;                                                    //接收ID为0x80的报文
        rfilter[3].can_mask = CAN_SFF_MASK;
        
        rfilter[4].can_id = 0x800;                                                    //接收ID为0x800的报文
        rfilter[4].can_mask = CAN_EFF_MASK;
        
        if( setsockopt( s,SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
                                sizeof(rfilter) ) != 0 )                            //设置过滤规则
        {
            perror("setsockopt");
            exit(1);
        }
        
        /*服务端地址*/
        struct sockaddr_in server_addr;
        bzero( &server_addr, sizeof(server_addr) );
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr(ipaddr);
        server_addr.sin_port = htons(SERVER_PORT);
        addrlen = sizeof(server_addr);
        
        /*创建socket*/
        int client_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if( client_socket_fd == -1 )
        {
            perror("Creat Socket Failed!");
            exit(1);
        }
        
        /*数据传输*/
        while(1)
        {
            /*can接收数据*/
            if( nbytes = read(s, &frame, sizeof(frame)) < 0 )
            {
                perror("read");
                return 1;
            }
    
            switch(frame.can_id)
                {
                    case 0x10:
                        abuf[0] = ((frame.can_id>>24)&0xFF);
                        abuf[1] = ((frame.can_id>>16)&0xFF);
                        abuf[2] = ((frame.can_id>>8)&0xFF);
                        abuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            abuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d abuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, abuf[i]);
                        }
                        break;
                        
                    case 0x20:
                        bbuf[0] = ((frame.can_id>>24)&0xFF);
                        bbuf[1] = ((frame.can_id>>16)&0xFF);
                        bbuf[2] = ((frame.can_id>>8)&0xFF);
                        bbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            bbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d bbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, bbuf[i]);
                        }
                        break;
                        
                    case 0x40:
                        cbuf[0] = ((frame.can_id>>24)&0xFF);
                        cbuf[1] = ((frame.can_id>>16)&0xFF);
                        cbuf[2] = ((frame.can_id>>8)&0xFF);
                        cbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            cbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d cbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, cbuf[i]);
                        }
                        break;
                        
                    case 0x80:
                        dbuf[0] = ((frame.can_id>>24)&0xFF);
                        dbuf[1] = ((frame.can_id>>16)&0xFF);
                        dbuf[2] = ((frame.can_id>>8)&0xFF);
                        dbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            dbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d dbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, dbuf[i]);
                        }
                        break;
                        
                    case 0x80000800:
                        ebuf[0] = ((frame.can_id>>24)&0xFF);
                        ebuf[1] = ((frame.can_id>>16)&0xFF);
                        ebuf[2] = ((frame.can_id>>8)&0xFF);
                        ebuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            ebuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d ebuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, ebuf[i]);
                        }
                        break;
                        
                    default :
                        printf("The recive can indetifer ID is wrong!
    ");
                        break;
                }
            
            sendto(client_socket_fd,abuf,12,0,(struct sockaddr*)&server_addr, addrlen);
            sendto(client_socket_fd,bbuf,12,0,(struct sockaddr*)&server_addr, addrlen);
            sendto(client_socket_fd,cbuf,12,0,(struct sockaddr*)&server_addr, addrlen);
            sendto(client_socket_fd,dbuf,12,0,(struct sockaddr*)&server_addr, addrlen);
            sendto(client_socket_fd,ebuf,12,0,(struct sockaddr*)&server_addr, addrlen);
            printf("Hello.
    ");
            
            /*接收数据*/
            /*
            size_t recv_len = 0;
            char buffer[BUFFER_SIZE];
            bzero(buffer, BUFFER_SIZE);
            recv_len = recvfrom(server_socket_fd, buffer, BUFFER_SIZE, 0 ,(struct sockaddr*)&client_addr,                                                                             &client_addr_length);
            if( recv_len == -1 )
            {
                perror("Receive Data Failed:");
                exit(1);
            }
            */
            /*从buffer中拷贝出file_name*/
            /*
            char file_name[FILE_NAME_MAX_SIZE +1];
            bzero(file_name,FILE_NAME_MAX_SIZE+1);
            strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
            printf("%s
    ",file_name);
            printf("%s
    ",buffer);
            */
            
        }
            system("ip link set can0 down");
            close(client_socket_fd);
            return 0;
    }

    编译生成client_can 使用说明:

    1、运行可执行文件client_can(./client_can)
    2、利用网络调试工具Socket_Tool.exe(F:嵌入式资料AM335XBeagleBoneUDP_testSocket_Tool.exe)
        创建服务其端口:
            a、192.168.200.11080003、另一快开发板can0设置:
        a、ip link set can0 down
        b  ip link set can0 type can bitrate 125000 triple-sampling on
        c  ip link set can0 up
        d  cansend can0 -i 0x80 0xaa 0x11 0x55 0x44 0x11 0x22 0x33 0x66
    4、当can0的CANL、CANH上面有数据时:运行。/client_can的开发板就可以接收的相应的数据(
            ID=0x80 DLC=8 dbuf[4]=0x55
            ID=0x80 DLC=8 dbuf[5]=0x55
            ID=0x80 DLC=8 dbuf[6]=0x55
            ID=0x80 DLC=8 dbuf[7]=0x55
            ID=0x80 DLC=8 dbuf[8]=0xaa
            ID=0x80 DLC=8 dbuf[9]=0xaa
            ID=0x80 DLC=8 dbuf[10]=0xaa
            ID=0x80 DLC=8 dbuf[11]=0xac
            Hello.
    
    ),同时将数据通过网络发送给PC机的server服务器端
    (
            14:59:16 收到数据:{00 00 00 10 55 55 55 55 AA AA AA AC }
            14:59:16 收到数据:{14 69 69 0D 00 79 FE B6 02 00 00 00 }ii
            14:59:16 收到数据:{24 08 00 00 00 00 00 00 08 FD F7 BE }$
            14:59:16 收到数据:{00 00 00 80 55 55 55 55 AA AA AA AC }
            14:59:16 收到数据:{B8 7B FC B6 00 00 00 00 4D 8C 00 00 }竰�
    )。
    
        

     PC端的服务器端口配置:

    服务器端口:

    /********************************************************************
    *       copyright (C) 2018 all rights reserved
    *            @file: server.c
    *         @Created: 2018-4-16 13:22nd 
    *          @Author: Yinrui Zhu
    *     @Description: test user eth0 
    *     @Modify Date: 2018-4-13
    *********************************************************************/
    
    #include <limits.h>
    #include <stdint.h>
    #include <getopt.h>
    #include <libgen.h>
    #include <signal.h>
    #include <net/if.h>
    #include <sys/ioctl.h>
    #include <linux/can.h>
    #include <linux/can/raw.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <pthread.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    #define SERVER_PORT 8000
    #define BUFFER_SIZE 1024
    #define ipaddr "192.168.200.110"
    #define FILE_NAME_MAX_SIZE 512
    
    int main()
    {
        int nbytes,i,addrlen;
        char abuf[12];
        char bbuf[12];
        char cbuf[12];
        char dbuf[12];
        char ebuf[12];
        
        int s;
        struct sockaddr_can addr;
        struct ifreq ifr;
        struct can_frame frame;
        struct can_filter rfilter[5];
        int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW;
        
        system("ip link set can0 type can bitrate 125000 triple-sampling on");
        sleep(2);
        system("ip link set can0 up");
        
        s = socket(family, type, proto);                                            //创建套接字
        
        strcpy(ifr.ifr_name, "can0");
        ioctl(s, SIOCGIFINDEX,&ifr);                                                //指定can0设备
        
        addr.can_family = family;
        //addr.can_family = AF_CAN;
        addr.can_ifindex = ifr.ifr_ifindex;
        bind( s, (struct sockaddr *)&addr, sizeof(addr) );                            //将套接字与can0设备绑定
        
        /*定义接收规则*/
        rfilter[0].can_id = 0x10;                                                    //接收ID为0x10的报文
        rfilter[0].can_mask = CAN_SFF_MASK;
        
        rfilter[1].can_id = 0x20;                                                    //接收ID为0x20的报文
        rfilter[1].can_mask = CAN_SFF_MASK;
        
        rfilter[2].can_id = 0x40;                                                    //接收ID为0x40的报文
        rfilter[2].can_mask = CAN_SFF_MASK;
        
        rfilter[3].can_id = 0x80;                                                    //接收ID为0x80的报文
        rfilter[3].can_mask = CAN_SFF_MASK;
        
        rfilter[4].can_id = 0x800;                                                    //接收ID为0x800的报文
        rfilter[4].can_mask = CAN_EFF_MASK;
        
        if( setsockopt( s,SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
                                sizeof(rfilter) ) != 0 )                            //设置过滤规则
        {
            perror("setsockopt");
            exit(1);
        }
        
        /*创建UDP套接口*/
        struct sockaddr_in server_addr;
        bzero( &server_addr, sizeof(server_addr) );
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(SERVER_PORT);
        
        /*创建socket*/
        int server_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if( server_socket_fd == -1 )
        {
            perror("Creat Socket Failed!");
            exit(1);
        }
        
        /*绑定套接口*/
        if(-1 == ( bind( server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr) ) ) )
        {
            perror("Server Bind Failed: ");
            exit(1);
        }
        
        /*数据传输*/
        while(1)
        {
            /*can接收数据*/
            if( nbytes = read(s, &frame, sizeof(frame)) < 0 )
            {
                perror("read");
                return 1;
            }
    
            switch(frame.can_id)
                {
                    case 0x10:
                        abuf[0] = ((frame.can_id>>24)&0xFF);
                        abuf[1] = ((frame.can_id>>16)&0xFF);
                        abuf[2] = ((frame.can_id>>8)&0xFF);
                        abuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            abuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d abuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, abuf[i]);
                        }
                        break;
                        
                    case 0x20:
                        bbuf[0] = ((frame.can_id>>24)&0xFF);
                        bbuf[1] = ((frame.can_id>>16)&0xFF);
                        bbuf[2] = ((frame.can_id>>8)&0xFF);
                        bbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            bbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d bbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, bbuf[i]);
                        }
                        break;
                        
                    case 0x40:
                        cbuf[0] = ((frame.can_id>>24)&0xFF);
                        cbuf[1] = ((frame.can_id>>16)&0xFF);
                        cbuf[2] = ((frame.can_id>>8)&0xFF);
                        cbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            cbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d cbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, cbuf[i]);
                        }
                        break;
                        
                    case 0x80:
                        dbuf[0] = ((frame.can_id>>24)&0xFF);
                        dbuf[1] = ((frame.can_id>>16)&0xFF);
                        dbuf[2] = ((frame.can_id>>8)&0xFF);
                        dbuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            dbuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d dbuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, dbuf[i]);
                        }
                        break;
                        
                    case 0x80000800:
                        ebuf[0] = ((frame.can_id>>24)&0xFF);
                        ebuf[1] = ((frame.can_id>>16)&0xFF);
                        ebuf[2] = ((frame.can_id>>8)&0xFF);
                        ebuf[3] = (frame.can_id&0xFF);
                        for( i=4; i<frame.can_dlc+4; i++)
                        {
                            ebuf[i] = frame.data[i-4];
                            printf("ID=0x%x DLC=%d ebuf[%d]=0x%x
    ", frame.can_id, frame.can_dlc, i, ebuf[i]);
                        }
                        break;
                        
                    default :
                        printf("The recive can indetifer ID is wrong!
    ");
                        break;
                }
            
            /*定义一个地址,用于蒱获客户端地址*/
            struct sockaddr_in client_addr;
            socklen_t client_addr_length = sizeof(client_addr);
            
            /*接收数据*/
            size_t recv_len = 0;
            char buffer[BUFFER_SIZE];
            bzero(buffer, BUFFER_SIZE);
            recv_len = recvfrom(server_socket_fd, buffer, BUFFER_SIZE, 0 ,(struct sockaddr*)&client_addr,                                                                             &client_addr_length);
            if( recv_len == -1 )
            {
                perror("Receive Data Failed:");
                exit(1);
            }
            
            /*从buffer中拷贝出file_name*/
            char file_name[FILE_NAME_MAX_SIZE +1];
            bzero(file_name,FILE_NAME_MAX_SIZE+1);
            strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
            printf("%s
    ",file_name);
            printf("%s
    ",buffer);
            
            sendto(server_socket_fd,buffer,recv_len,0,(struct sockaddr*)&client_addr, client_addr_length);
            
            sendto(server_socket_fd,abuf,12,0,(struct sockaddr*)&client_addr, client_addr_length);
            sendto(server_socket_fd,bbuf,12,0,(struct sockaddr*)&client_addr, client_addr_length);
            sendto(server_socket_fd,cbuf,12,0,(struct sockaddr*)&client_addr, client_addr_length);
            sendto(server_socket_fd,dbuf,12,0,(struct sockaddr*)&client_addr, client_addr_length);
            sendto(server_socket_fd,ebuf,12,0,(struct sockaddr*)&client_addr, client_addr_length);
            printf("Hello.
    ");
            
        }
            system("ip link set can0 down");
            close(server_socket_fd);
            return 0;
    }

    PC端客户端配置:

    编译生成server.can 使用说明:

    1、运行可执行文件server_can(./server_can)
    2、利用网络调试工具Socket_Tool.exe(F:嵌入式资料AM335XBeagleBoneUDP_testSocket_Tool.exe)
        创建客户端口:
            a、192.168.200.7080003、另一快开发板can0设置:
        a、ip link set can0 down
        b  ip link set can0 type can bitrate 125000 triple-sampling on
        c  ip link set can0 up
        d  cansend can0 -i 0x80 0xaa 0x11 0x55 0x44 0x11 0x22 0x33 0x66
    4、当can0的CANL、CANH上面有数据时:运行。/server_can的开发板就可以接收的相应的数据(
            ID=0x80 DLC=8 dbuf[4]=0x55
            ID=0x80 DLC=8 dbuf[5]=0x55
            ID=0x80 DLC=8 dbuf[6]=0x55
            ID=0x80 DLC=8 dbuf[7]=0x55
            ID=0x80 DLC=8 dbuf[8]=0xaa
            ID=0x80 DLC=8 dbuf[9]=0xaa
            ID=0x80 DLC=8 dbuf[10]=0xaa
            ID=0x80 DLC=8 dbuf[11]=0xac
            Hello.
    
    ),但是接收到的数据只能发送一次。因为该板子作为服务器端口,需要客户端给该板子发送一个信号(any)。最为客户端的PC机才能接收服务器端(开发板)发过来的数据
    (
            5:13:26 收到数据:{24 08 00 00 00 00 00 00 08 DD D4 BE }$
            15:13:26 收到数据:{28 01 00 00 99 87 00 00 C5 8F 00 00 }(
            15:13:26 收到数据:{B8 3B F1 B6 00 00 00 00 91 8F 00 00 }?15:13:28 发送数据:猍1次]
            15:13:28 收到数据:{AA }
            15:13:28 收到数据:{00 00 00 10 55 55 55 55 AA AA AA AC }
            15:13:28 收到数据:{14 69 69 0D 00 39 F3 B6 02 00 00 00 }ii
            15:13:28 收到数据:{24 08 00 00 00 00 00 00 08 DD D4 BE }$
            15:13:28 收到数据:{28 01 00 00 99 87 00 00 C5 8F 00 00 }(
            15:13:28 收到数据:{B8 3B F1 B6 00 00 00 00 91 8F 00 00 }?穸
    )。
        
  • 相关阅读:
    C#--事件驱动在上位机中的应用【一】(搭建仿真PLC环境)
    C#--事件驱动在上位机中的应用【三】(自定义控件)
    C#--事件驱动在上位机中的应用【二】(自定义控件)
    C#--属性--propfull和prop使用场所
    C#--通过Modbus TCP与西门子1200PLC通讯
    C#--简单调用WebService
    C#-- 简单新建WebService服务
    C#--发布WebService和部署IIS到本地服务器
    P1909 买铅笔
    P1089 津津的储蓄计划
  • 原文地址:https://www.cnblogs.com/BigOBlue/p/9036398.html
Copyright © 2020-2023  润新知