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\n", 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\n", 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\n", 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\n", 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\n", frame.can_id, frame.can_dlc, i, ebuf[i]);
                    }
                    break;
                    
                default :
                    printf("The recive can indetifer ID is wrong!\n");
                    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.\n");
        
        /*接收数据*/
        /*
        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\n",file_name);
        printf("%s\n",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:\嵌入式资料\AM335X\BeagleBone\UDP_test\Socket_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 }竰
)。

    

服务器端口:

/********************************************************************
*       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\n", 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\n", 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\n", 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\n", 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\n", frame.can_id, frame.can_dlc, i, ebuf[i]);
                    }
                    break;
                    
                default :
                    printf("The recive can indetifer ID is wrong!\n");
                    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\n",file_name);
        printf("%s\n",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.\n");
        
    }
        system("ip link set can0 down");
        close(server_socket_fd);
        return 0;
}

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

1、运行可执行文件server_can(./server_can)
2、利用网络调试工具Socket_Tool.exe(F:\嵌入式资料\AM335X\BeagleBone\UDP_test\Socket_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 }?穸
)。
    

猜你喜欢

转载自www.cnblogs.com/BigOBlue/p/9036398.html