zoukankan      html  css  js  c++  java
  • Linux客户端网口输入转串口输出

    概要与环境

    使用socket通信方式,建立连接,在服务端将获取到的数据调用串口发送即可

    服务端为Linux,客户端为Linux或Windows

    测试过程中请:使用iptables -F,免得让人感觉不好。

    另外,在Linux下的C语言头文件一部分不可以在Windows系统上运行,可能导致一些不便。

    socket通信

    参阅:https://www.cnblogs.com/wuyepeng/p/9717236.html

    要真正实现合适的通信,仍然需要加之修改。在本例测试过程中,发送端的输出数据在接收端会多出两个字节长度。相信是在发送端造成的。

    C客户端的测试代码基本相同:

     1 #include <sys/types.h>
     2 #include <sys/socket.h>
     3 #include <stdio.h>
     4 #include <netinet/in.h>
     5 #include <arpa/inet.h>
     6 #include <unistd.h>
     7 #include <string.h>
     8 #include <stdlib.h>
     9 #include <fcntl.h>
    10 #include <sys/shm.h>
    11  
    12 #define MYPORT  8887
    13 #define BUFFER_SIZE 1024
    14  
    15 int main()
    16 {
    17     ///定义sockfd
    18     int sock_cli = socket(AF_INET,SOCK_STREAM, 0);
    19  
    20     ///定义sockaddr_in
    21     struct sockaddr_in servaddr;
    22     memset(&servaddr, 0, sizeof(servaddr));
    23     servaddr.sin_family = AF_INET;
    24     servaddr.sin_port = htons(MYPORT);  ///服务器端口
    25     servaddr.sin_addr.s_addr = inet_addr("xxxxxx");  ///服务器ip
    26  
    27     ///连接服务器,成功返回0,错误返回-1
    28     if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    29     {
    30         perror("connect");
    31         exit(1);
    32     }
    33  
    34     char sendbuf[BUFFER_SIZE];
    35     char recvbuf[BUFFER_SIZE];
    36     while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    37     {
    38 //    int len = strlen(sendbuf);
    39 //    if(sendbuf[len-1] == '
    '){sendbuf[len--]=0;}
    40     printf("send:%s",sendbuf);
    41         send(sock_cli, sendbuf, strlen(sendbuf),0); ///发送
    42         recv(sock_cli, recvbuf, strlen(recvbuf),0); ///接收
    43         fputs(recvbuf, stdout);
    44         memset(sendbuf, 0, sizeof(sendbuf));
    45         memset(recvbuf, 0, sizeof(recvbuf));
    46     }
    47     close(sock_cli);
    48     return 0;
    49 }
    View Code

    C服务端的测试代码:该代码存在致命的缺陷未修正。运行以后,在客户一端敲入几次回车即可显示。

     1 #include <sys/types.h>
     2 #include <sys/socket.h>
     3 #include <stdio.h>
     4 #include <netinet/in.h>
     5 #include <arpa/inet.h>
     6 #include <unistd.h>
     7 #include <string.h>
     8 #include <stdlib.h>
     9 #include <fcntl.h>
    10 #include <sys/shm.h>
    11 #include <asm/termios.h>
    12 #define DEV_NAME  "/dev/pts/1"
    13 #define MYPORT  8887
    14 #define QUEUE   20
    15 #define BUFFER_SIZE 1024
    16 
    17 int mainFunction()
    18 {
    19     int fd;//serial port
    20     ///定义sockfd
    21     int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
    22 
    23     ///定义sockaddr_in
    24     struct sockaddr_in server_sockaddr;
    25     server_sockaddr.sin_family = AF_INET;
    26     server_sockaddr.sin_port = htons(MYPORT);
    27     server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    28 
    29     fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
    30     if(fd < 0) 
    31     {
    32             perror(DEV_NAME);
    33             return -1;
    34     }
    35     printf("%d port is ready
    ");
    36     ///bind,成功返回0,出错返回-1
    37     while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
    38     {;
    39     }
    40 
    41     ///listen,成功返回0,出错返回-1
    42     if(listen(server_sockfd,QUEUE) == -1)
    43     {
    44         perror("listen error
    ");
    45         return;
    46     }
    47 
    48     ///客户端套接字
    49     char buffer[BUFFER_SIZE];
    50     struct sockaddr_in client_addr;
    51     socklen_t length = sizeof(client_addr);
    52 
    53     ///成功返回非负描述字,出错返回-1
    54     int conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
    55     if(conn<0)
    56     {
    57         perror("connect error
    ");
    58         return;
    59     }
    60 
    61     while(1)
    62     {
    63         memset(buffer,0,sizeof(buffer));
    64         int len = recv(conn, buffer, sizeof(buffer),0);
    65         if(len<=0)
    66         {
    67             printf("maybe disconnected... restart:
    ");
    68             break;
    69         }
    70         fputs(buffer, stdout);
    71         send(conn, strcat("send message success:",buffer), len, 0);
    72     }
    73     close(conn);
    74     close(server_sockfd);
    75 
    76 }
    77 void main()
    78 {
    79     while(1)
    80     {
    81         mainFunction();
    82     }
    83 }
    View Code

    python实现通信参阅:https://blog.csdn.net/su_bao/article/details/80380465

    python实现的通信更加方便。阅读链接信息即可。该python的客户端程序,修改参数可以直接与C语言的socket服务端通信。通信过程中,接收端和发送的字节数相同。

    该代码在python2中可能输入数据需要添加双引号,

    串口控制

    串口部分可以参阅:周立功【开发指南】M6G2C&A6G2C;系列核心板软件开发指南。

    该指南中,在第16章,有详细的串口发送案例。其中也详细的书写了一些自定义参数的函数,可供使用。

    以下是基本相同的示例代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <fcntl.h>
     5 #include <asm/termios.h>
     6 #define DEV_NAME  "/dev/pts/1"
     7 int main (int argc, char *argv[])
     8 {
     9     int fd;
    10     int len, i,ret;
    11     char buf[] = "hello ZLG!";
    12 
    13     fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
    14     if(fd < 0) {
    15             perror(DEV_NAME);
    16             return -1;
    17     }
    18     printf("%d",fd);
    19     len = write(fd, buf, sizeof(buf));
    20     if (len < 0) {
    21         printf("write data error 
    ");
    22     }
    23     printf("%s", buf);
    24     return(0);
    25 }
    View Code

    另外需要测试的是串口控制,则需要使用虚拟串口。

    这里可以采用他人python写的一个虚拟串口脚本,建立两个互通的串口?:https://blog.csdn.net/qq_42973043/article/details/82888075

    这里可以做出一些删减后的代码,基本相同如下:

     1 import pty
     2 import os
     3 import select
     4 
     5 def mkpty():
     6     #
     7     master1, slave = pty.openpty()
     8     slaveName1 = os.ttyname(slave)
     9     master2, slave = pty.openpty()
    10     slaveName2 = os.ttyname(slave)
    11     print '/nslave device names: ', slaveName1, slaveName2
    12     return master1, master2
    13 
    14 if __name__ == "__main__":
    15 
    16     master1, master2 = mkpty()
    17     while True:        
    18         rl, wl, el = select.select([master1,master2], [], [], 1)
    19         for master in rl:
    20             data = os.read(master, 128)
    21             if master==master1:
    22                 print "master1 receive data: %d data:" % len(data)
    23                 print data
    24             else:
    25                 print "master2 receive data: %d data:" % len(data)
    26                 print data
    View Code

    测试方式相同。

    综合

    修正部分如下,该部分去掉了一些错误。

    1     while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
    2     {
    3         
    4     ;
    5     }
    View Code

    C语言服务端完整代码如下

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <asm/termios.h>
    #define DEV_NAME  "/dev/pts/1"
    #define MYPORT  8887
    #define QUEUE   20
    #define BUFFER_SIZE 1024
    
    int mainFunction()
    {
        int fd;//serial port
        ///定义sockfd
        int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
    
        ///定义sockaddr_in
        struct sockaddr_in server_sockaddr;
        server_sockaddr.sin_family = AF_INET;
        server_sockaddr.sin_port = htons(MYPORT);
        server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
    	if(fd < 0) 
    	{
    			perror(DEV_NAME);
    			return -1;
    	}
        printf("port is ready
    ");
        cfsetispeed(fd,115200);
        cfsetospeed(fd,115200);
        //bind,成功返回0,出错返回-1
        while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
        {
            
    	;
        }
        ///listen,成功返回0,出错返回-1
        if(listen(server_sockfd,QUEUE) == -1)
        {
            perror("listen error
    ");
    	return;
        }
        ///客户端套接字
        char buffer[BUFFER_SIZE];
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
    
        ///成功返回非负描述字,出错返回-1
        int conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
        if(conn<0)
        {
            perror("connect error
    ");
    	return;
        }
    
        while(1)
        {
            memset(buffer,0,sizeof(buffer));
            int len = recv(conn, buffer, sizeof(buffer),0);
    	if(len<=0)
            {
                printf("maybe disconnected... restart:
    ");
                break;
            }
    //	if(buffer[0]=='
    ')
    //	{
    //	    printf("end by user");
    //	    break;
    //	}
    	len = write(fd, buffer,len);
    	if (len < 0) {
    		printf("write data error 
    ");
    		break;
    	}
            send(conn,buffer, len, 0);
        }
        close(conn);
        close(server_sockfd);
    
    }
    void main()
    {
        while(1)
        {
            mainFunction();
        }
    }
    

    当然啦,一个用户还可以,要是多个用户,那就用多线程喽

    代码折起不会长

     编译命令:gcc -lpthread server.c -o server

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <asm/termios.h>
    #include <pthread.h>
    #define DEV_NAME  "/dev/pts/1"
    #define MYPORT  8887
    #define QUEUE   20
    #define BUFFER_SIZE 1024
    
    int fd;//serial port
    void * recvMsg(void *con)
    {
        char buffer[BUFFER_SIZE];
        int conn=(int)*(int *)con;
        int len;
        while(1)
        {
            memset(buffer,0,sizeof(buffer));
            len=recv(conn, buffer, sizeof(buffer),0);
    
            if( len<=0 ){printf("maybe disconnected... 
    ");break;}
            if( write(fd, buffer,len)< 0 ) {printf("write data error 
    ");break;}
    
            send(conn,buffer, len, 0);
        }
        close(conn);
        pthread_exit(NULL);
    }
    
    int mainFunction()
    {
    
        fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
        if(fd < 0) 
        {
                printf("DEV_NAME ERROR!");
                return -1;
        }
        printf("port is ready
    ");
        cfsetispeed(fd,115200);
        cfsetospeed(fd,115200);
    
        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 = htonl(INADDR_ANY);
    
        while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1);
        if(listen(server_sockfd,QUEUE) == -1){return;}
    
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
    
        while(1)
        {
            int conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);if(conn<0){continue;}
            pthread_t recv_thread;
            pthread_create(&recv_thread, NULL, recvMsg,(void *)&conn);
        }
        close(server_sockfd);
    
    }
    void main()
    {
        while(1)
        {
            mainFunction();
        }
    }
    

      

    单用户的异步双向转发

    服务端的C

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <asm/termios.h>
    #include <pthread.h>
    #define DEV_NAME  "/dev/ttyS2"
    #define MYPORT  8887
    #define QUEUE   20
    #define BUFFER_SIZE 1024
    
    int fd;//serial port
    
    
    void * recvCom(void *con)
    {
        int len;
        char buffer[BUFFER_SIZE];
        int conn=(int)*(int *)con;
        while(1)
        {
            len=read(fd, buffer, sizeof(buffer));
            if(len>0)
            {
                printf("receive:%s",buffer);
                send(conn,"you receive:", 12, MSG_DONTWAIT);
                send(conn,buffer, len, MSG_DONTWAIT);
            }
        }
    
    }
    
    void * recvSocket(void *con)
    {
        char buffer[BUFFER_SIZE];
        int conn=(int)*(int *)con;
        int len;
        printf("connected
    ");
        pthread_t recv_comm;
        pthread_create(&recv_comm, NULL, recvCom,(void *)&conn);
        while(1)
        {
            memset(buffer,0,sizeof(buffer));
            len=recv(conn, buffer, sizeof(buffer),0);
     
            if( len<=0 ){printf("maybe disconnected... 
    ");pthread_cancel(recv_comm);break;}
            if( write(fd, buffer,len)< 0 ) {printf("write data error 
    ");break;}
            send(conn,"you send:", 9, 0);
            send(conn,buffer, len, 0);
        }
        close(conn);
        //pthread_exit(NULL);
    }
    
    
    void * socketAndSerial(void *con)
    {
        int conn=(int)*(int *)con;
        recvSocket((void *)&conn);
    }
    int mainFunction()
    {
     
        fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
        if(fd < 0) 
        {
                printf("DEV_NAME ERROR!");
                return -1;
        }
        printf("port is ready
    ");
        cfsetispeed(fd,115200);
        cfsetospeed(fd,115200);
     
        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 = htonl(INADDR_ANY);
     
        while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1);
        if(listen(server_sockfd,QUEUE) == -1){return;}
     
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
     
        int conn=-1;
        while((conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length))<0);
        close(server_sockfd);
        socketAndSerial((void *)&conn);
    }
    void main()
    {
        while(1)
        {
            mainFunction();
        }
    }
    

    客户端的Python

    from socket import *
    import threading
    import ctypes
    import inspect
    HOST = '192.168.0.78' # or 'localhost'
    PORT = 8887
    BUFSIZ =1024
    ADDR = (HOST,PORT)
    
    tcpCliSock = socket(AF_INET,SOCK_STREAM)
    tcpCliSock.connect(ADDR)
    
    def _async_raise(tid, exctype):
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")
    
    def readBuffer():
        while True:
            data1 = tcpCliSock.recv(BUFSIZ)
            print(data1.decode('utf-8'))
    
    
    a=threading.Thread(target=readBuffer,args=())
    a.start()
                     
    while True:
         data1 = input('>')
         #data = str(data)
         if not data1:
            _async_raise(a.ident, SystemExit)
            break
         tcpCliSock.send((data1).encode())
    
    tcpCliSock.close()
    
    
     
    

      

    更正可使用的16进制转发,用户完全传输

    服务端

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <asm/termios.h>
    #include <pthread.h>
    #define DEV_NAME  "/dev/ttyS2"
    #define MYPORT  8887
    #define QUEUE   20
    #define BUFFER_SIZE 1024
    
    int fd;//serial port
    
    
    void * recvCom(void *con)
    {
        int len;
        char buffer[BUFFER_SIZE];
        int conn=(int)*(int *)con;
        int i;
        while(1)
        {
            len=read(fd, buffer, sizeof(buffer));
            if(len>0)
            {
                char *p=buffer;
                printf("serial msg:");
                for(i=0;i<len;i++)
                        printf("%2x ",buffer[i]);
                printf("
    ");
                send(conn,"you receive:", 12, MSG_DONTWAIT);
                send(conn,buffer, len, MSG_DONTWAIT);
            }
        }
    
    }
    
    void * recvSocket(void *con)
    {
        char buffer[BUFFER_SIZE];
        int conn=(int)*(int *)con;
        int len;
        int i;
        printf("connected
    ");
        pthread_t recv_comm;
        pthread_create(&recv_comm, NULL, recvCom,(void *)&conn);
        while(1)
        {
            memset(buffer,0,sizeof(buffer));
            len=recv(conn, buffer, sizeof(buffer),0);
            printf("socket msg:");
            for(i=0;i<len;i++)
                    printf("%2x ",buffer[i]);
            printf("
    ");
            if( len<=0 ){printf("maybe disconnected... 
    ");pthread_cancel(recv_comm);break;}
            if( write(fd, buffer,len)< 0 ) {printf("write data error 
    ");break;}
            send(conn,"you send:", 9, 0);
            send(conn,buffer, len, 0);
        }
        close(conn);
        //pthread_exit(NULL);
    }
    
    
    void * socketAndSerial(void *con)
    {
        int conn=(int)*(int *)con;
        recvSocket((void *)&conn);
    }
    int mainFunction()
    {
     
        fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
        if(fd < 0) 
        {
                printf("DEV_NAME ERROR!");
                return -1;
        }
        printf("port is ready
    ");
        cfsetispeed(fd,115200);
        cfsetospeed(fd,115200);
     
        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 = htonl(INADDR_ANY);
     
        while(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1);
        if(listen(server_sockfd,QUEUE) == -1){return;}
     
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
     
        int conn=-1;
        while((conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length))<0);
        close(server_sockfd);
     
        socketAndSerial((void *)&conn);
        
    }
    void main()
    {
        while(1)
        {
            mainFunction();
        }
    }
    

    用户端

    from socket import *
    import threading
    import ctypes
    import inspect
    HOST = '192.168.0.78' # or 'localhost'
    PORT = 8887
    BUFSIZ =1024
    ADDR = (HOST,PORT)
    
    tcpCliSock = socket(AF_INET,SOCK_STREAM)
    tcpCliSock.connect(ADDR)
    
    def _async_raise(tid, exctype):
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")
    
    def readBuffer():
        while True:
            data1 = tcpCliSock.recv(BUFSIZ)
            print(data1)
    
    
    a=threading.Thread(target=readBuffer,args=())
    a.start()
                     
    while True:
         data1 = input('>')
         #data = str(data)
         if not data1:
            break
         tcpCliSock.send((data1).encode())
         
    _async_raise(a.ident, SystemExit)
    tcpCliSock.close()
    
  • 相关阅读:
    vivo 全球商城:从 0 到 1 代销业务的融合之路
    mysql 批量kill掉运行中的进程id
    启用php-fpm状态功能 --php-fpm调优也有
    PHP-php-fpm配置优化
    Linux-cpu分析-vmstat
    关于overflow:hidden的作用(溢出隐藏、清除浮动、解决外边距塌陷等等)
    curl 发送POST请求
    python redis-rdb工具 分析redis工具
    tupdump
    spring cloud gateway security oauth2
  • 原文地址:https://www.cnblogs.com/bai2018/p/12501480.html
Copyright © 2011-2022 走看看