串口通信+TCP网络通信简单综合实例

2023-05-16

串口通信+TCP网络通信简单综合实例

串口通信加上TCP网络通信之后就可以简单实现本地设备的联网功能了,哈哈,话不多说,直接上代码。

总体上还是C/S模式,但是这个客户端加上了对串口的操作而已,思路很简单,只不过应用过程中可能会碰到一些棘手的问题,比如和终端的交互协议采用什么,协议的复杂程度如何,通信时的同步问题,稳定性问题等等。这里我们都先不去考虑,下面的代码仅仅只是设备利用串口实现了和远程服务器的通信,还未做任何优化。

1.服务器部分:服务器基本不变,只需要和客户端进行通信即可,和串口无任何交互。所以其代码不变,和TCP网络通信的服务端代码相同。

 

/*
 * 文件:tcp_server.c
 * 内容:利用TCP实现客户端和服务器的实时聊天。
 * 注  :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。
 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。
 * 编译:gcc tcp_server.c -o ser -lpthread
 * 运行:./ser 127.0.0.1 7788 5
 */
 
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#include<errno.h>
#include<pthread.h>
#include<arpa/inet.h>
 
#define SPORT 1111
#define CPORT 2222
#define IP "127.0.0.1"
#define MAXLEN 1024
 
struct network_info
{
    struct sockaddr addr;
    int addr_len;
    int sock;
}target = {0,0,0};
 
void* myrecv(void* arg)
{
    int new_fd = 0,len = 0;
    char buf[MAXLEN] = {'\0'};
    time_t t;
    struct network_info netinfo;
    netinfo = *((struct network_info*)arg);
    new_fd = netinfo.sock;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf)-1);
        len = recv(new_fd,buf,sizeof(buf) - 1,0);
        if(len > 0)
        {
            t = time(NULL);
            printf("&client:%s    @%s\n",buf,ctime(&t));
        }
        else if(len < 0)
        {
            printf("recv msg error,error code = %d,error msg = %s\n",errno,strerror(errno));
            break;
        }
        else
        {
            printf("client is quit\n");
            close(new_fd);
            break;
        }
    }
}
 
void* mysend(void* arg)
{
    int new_fd = 0,len = 0;
    char buf[MAXLEN] = {'\0'};
    struct network_info netinfo;
    netinfo = *((struct network_info*)arg);
 
    new_fd = netinfo.sock;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf));
 
        gets(buf);
        if(!strncasecmp(buf,"quit",4))
        {
            printf("I will close the connect\n");
            sleep(1);
            close(new_fd);
            exit(EXIT_FAILURE);
        }
 
        len = sendto(new_fd,buf,strlen(buf),0,(struct sockaddr*)(&(netinfo.addr)),netinfo.addr_len);
        if(len < 0)
        {
            printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno));
            break;
        }
    }
}
 
int main(int argc,char* argv[])
{
    int pid = 0,sock_fd = 0,new_fd = 0;
    socklen_t len;
    struct sockaddr_in self_addr,their_addr;
    unsigned int myport,lisnum;
    char buf[MAXLEN] = {'\0'};
    char ip[17] = {'\0'};
    time_t t;
    pthread_t pthread1,pthread2;
 
    if(argv[2] && argc >=3)
        myport = atoi(argv[2]);
    else
        myport = SPORT;
 
    if(argv[3] && argc >= 4)
        lisnum = atoi(argv[3]);
    else
        lisnum = 3;
 
    //创建套接字
    sock_fd = socket(AF_INET,SOCK_STREAM,0);
    if(sock_fd < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
 
    //绑定自己的端口号
    memset(&self_addr,0,sizeof(self_addr));
    self_addr.sin_family = AF_INET;
    self_addr.sin_port = htons(myport);
    if(argv[1])
        self_addr.sin_addr.s_addr = inet_addr(argv[1]);
    else
        self_addr.sin_addr.s_addr = INADDR_ANY;
 
    if(bind(sock_fd,(struct sockaddr*)&self_addr,sizeof(self_addr)) == -1)
    {
        perror("bind error");
        exit(EXIT_FAILURE);
    }
 
    //监听
    if(listen(sock_fd,lisnum) == -1)
    {
        perror("listen error");
        exit(EXIT_FAILURE);
    }
 
    //接受客户端的连接请求
    memset(&their_addr,0,sizeof(their_addr));
    len = sizeof(their_addr);
    printf("wait for connect\n");
    while(1)
    {
        if((new_fd = accept(sock_fd,(struct sockaddr*)&their_addr,&len)) == -1)
        {
            printf("len=%d,new_fd=%d\n",len,new_fd);
            perror("accept error");
            exit(EXIT_FAILURE);
        }
        printf("=====================================================================\n");
        printf("client connect ok\n");
        printf("though i am a server,but if you want to shutdown,please print 'quit'.\n");
        printf("=====================================================================\n");
        memcpy(&(target.addr),&(their_addr),len);
        target.addr_len = len;
        target.sock = new_fd;
 
        //创建线程用于进程间通信
        pthread_create(&pthread1,NULL,myrecv,(void*)&target);
        pthread_create(&pthread2,NULL,mysend,(void*)&target);
    }
 
    pthread_join(pthread1,NULL);
    pthread_join(pthread2,NULL);
    close(new_fd);
    close(sock_fd); //关闭套接字
 
    return 0;
}

 

 

 

 

 

2.客户端部分(加入了串口操作,而且在多线程操作时仅仅做了简单处理,对了,关于串口操作部分,大家可以去看我转载的串口编程博文)

 

/*
 * 文件:tcp_client.c
 * 内容:利用TCP实现客户端和服务器的实时聊天,以及串口操作。
 * 注  :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。
 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。
 * 编译:gcc tcp_client.c -o cli -lpthread
 * 运行:./cli 127.0.0.1 7788(注:这个是服务器端的地址和端口号)
 */
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include <arpa/inet.h>
#include<errno.h>
#include<time.h>
#include<pthread.h>
#include"uart0_open.h"
#include"uart0_init.h"
#include"uart0_send.h"
#include"uart0_recv.h"
#include"uart0_close.h"
 
#define IP "127.0.0.1"
#define SPORT 1111
#define CPORT 2222
#define MAXLEN 1024
 
int fd[2] = {0};
 
void* myrecv() //接收服务器信息后进行处理
{
    int len = 0;
    char buf[MAXLEN] = {'\0'};
    time_t t;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf)-1);
        len = recv(fd[0],buf,sizeof(buf) - 1,0);
        if(len > 0)
        {
            t = time(NULL);
            printf("**********************************\n");
            printf("&server:%s\n",buf);
            printf("**********************************\n");
            UART0_Send(fd[1],buf,strlen(buf)); //收到服务器消息后发给串口
            printf("@%s\n",ctime(&t));
        }
        else if(len < 0)
        {
            printf("recv msg errno,errno code = %d,errno msg = %s\n",errno,strerror(errno));
            break;
        }
        else
        {
            printf("connect server error,it will be quit in 3 seconds later...\n");
            sleep(3);
            exit(EXIT_FAILURE);
        }
    }
}
 
void* mysend() //发送信息给服务器
{
    int len = 0;
    char buf[MAXLEN] = {'\0'};
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf));
 
        UART0_Recv(fd[1],buf,sizeof(buf)-1); //从串口处获取要发送给服务器的信息
        if(!strncasecmp(buf,"quit",4))
        {
            printf("I will close the connect ...\n");
            sleep(1);
            exit(EXIT_FAILURE);
        }
        len = send(fd[0],buf,strlen(buf),0);
        if(len < 0)
        {
            printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno));
            break;
        }
    }
}
 
 
int main(int argc,char* argv[])
{
    int err = 0;
    socklen_t len;
    struct sockaddr_in their_addr;
    unsigned int their_port;
    char buf[MAXLEN] = {0};
    pthread_t pthread1,pthread2;
 
    //创建socket
    if((fd[0] = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
 
    //发送连接服务器的请求
    memset(&their_addr,0,sizeof(their_addr));
    their_addr.sin_family = AF_INET;
    if(argv[2] && argc >= 3)
        their_port = atoi(argv[2]);
    else
        their_port = SPORT;
    their_addr.sin_port = htons(their_port);
 
    if(argv[1] && argc >=2)
    {
        if(inet_aton(argv[1],(struct in_addr *)&their_addr.sin_addr.s_addr) == 0)
        {
            perror("argv[1]");
            exit(EXIT_FAILURE);
        }
    }
    else
        their_addr.sin_addr.s_addr = inet_addr(IP);
 
    if(connect(fd[0],(struct sockaddr*)(&their_addr),sizeof(their_addr)) == -1)
    {
        perror("connect error");
        exit(EXIT_FAILURE);
    }
 
    //打开串口,返回文件描述符
    fd[1] = UART0_Open(fd[1],"/dev/ttyS1");
    do {
        err = UART0_Init(fd[1],115200,0,8,1,'N');
        printf("set port exactly!\n");
    } while (-1 == err || -1 == fd[1]);
 
    printf("==============================================\n");
    printf("connect success!\n");
    printf("if you want to leave,please print 'quit'.\n");
    printf("==============================================\n");
 
    pthread_create(&pthread1,NULL,myrecv,NULL); //创建线程
    pthread_create(&pthread2,NULL,mysend,NULL);
 
    pthread_join(pthread1,NULL); //等待线程结束
    pthread_join(pthread2,NULL);
    UART0_Close(fd[1]); //关闭串口
    close(fd[0]); //关闭套接字
 
    return 1;
}

 

 

 

 

 

结果:记得选择合适版本的交叉编译器。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口通信+TCP网络通信简单综合实例 的相关文章

  • C++如何获取当前时间

    导读 文章首先介绍了使用C库的接口来获取当前时间的方法 xff0c 然后介绍了使用C 43 43 11标准库中的函数来获取当前时间的方法 此外 xff0c 文章还介绍了使用函数strftime来格式化时间字符串的方法 xff0c 并列举了常
  • Java笔记(一):volatile、synchronized关键字

    volatile关键字 volatile字面意思为易变的 不稳定的 xff0c 事实上也正是如此 这个关键字的作用就是告诉编译器 xff0c 只要是被此关键字修饰的变量都是易变的 xff0c 不稳定的 主要是volatile所修饰的变量是直
  • 读取cv.VideoCapture(0)的frame帧转变为PIL.Image图片格式时遇到的坑

    在项目中遇到一个问题是想将VideoCapture 读到的frame图片转变成PIL的Image图片格式 坑1 xff1a BGR还是RGB模式 xff1f 兴冲冲地在在网上找到一段代码 xff0c 将opencv中的imread 图像转成
  • linux命令记录

    linux三剑客 xff1a grep xff0c awk xff0c sed 1 grep命令 2 awk命令 linux中的awk命令是一种处理文本的工具 AWK命名来源于三位创始人的家族名称首字母 可以分行对文本进行处理 其命令格式如
  • [joysticker]使用Ubuntu读取USB手柄/方向盘的输出控制

    摘要 xff1a 在淘宝上买到的游戏手柄 USB卖家只给了Windows下的驱动 xff0c 本来以为Ubuntu下没有驱动 xff0c 没想到网上早已经有人用cpp开发出了USB手柄的驱动 xff0c 搜索很多博客的方法终于从手柄拿到数据
  • [numpy问题]The truth value of an array with more than one element is ambiguous.

    问题描述 xff1a 在进行Hough圆变换时 xff0c 需要输出一个圆的坐标 xff1a circles 61 cv2 span class hljs preprocessor HoughCircles span canny cv2 s
  • [PyQt5]点击主窗口弹出另一个窗口

    1 先使用Qt designer设计两个窗口 xff0c 一个是主窗口 xff0c 一个是子窗口 其中主窗口是新建 Main Window 子窗口是Dialog窗体 两个窗口不能是同一类型 否则会崩溃 并保存为EyeTracking mai
  • matlab的for循环

    https blog csdn net zhyoulun article details 78606382
  • 【总结】自然语言处理(NLP)算法:概述与分类

    摘要 xff1a NLP概述 主要参考自然语言处理 xff08 NLP xff09 知识结构总结和知乎上的一些问答 目录 NLP界神级人物NLP知识结构 1 概述2 形式语言与自动机3 语言模型4 概率图模型 xff0c 生成模型与判别模型
  • 【Win10】【开始菜单打不开】任务栏修复

    真是 xff0c 朋友说一句 xff0c 电脑出问题了你有本事别重装系统 我记住了 作为一个 强迫症患者 xff0c 最近电脑C盘内存快满以及翻墙代理污染了一部分ipv4网站就让我很毛 xff0c 很想重装系统 但是我忍住了 根据网上的教程
  • 「PyQt5」使用Qtdesigner设计好界面后写一个驱动程序

    使用Python写界面最方便的就是Pycharm 43 Qtdesigner 用Qt designer画用户界面比较容易 xff0c 保存成 ui文件然后转化成 py即可 这里 xff0c 我们展示下一步运行程序让这个界面显示 xff1a
  • 「git」Linux下将文件都上传到github上

    最近在整理自己平时写的一些代码 xff0c 第一选择就是上传到github上作为一个备份和说明 xff0c 防止自己遗忘 上次用版本控制已经是好几个月前了 xff0c 所以难免有些生疏 所以就从新按照CSDN大佬们的基础教程重新操作了一遍
  • 高质量嵌入式Linuxc编程

    第一天 xff1a 根目录 命令 注意 xff1a 命令和参数要区分开 xff0c 他们之间要有空格 cd 进入目录 ls 列举目录内容 ls a 列举所有文件包括隐藏的文件 所有隐藏的文件都是以点 xff08 xff09 开始的 ls l
  • 读写位宽不同的FIFO,数据输入输出顺序是怎么样的?BRAM又如何呢?

    原文地址 xff1a https wenku baidu com view 7d7cf156284ac850ac0242b6 html 对于BRAM xff1a 1 xff09 写位宽小于读位宽 xff1a 先入存低位 xff0c 后入存高
  • apache httpd在centos上手动安装

    Apache Bench手动安装 简介httpd及依赖包安装ab扩充最大并发量 简介 apache bench简称 xff08 ab xff09 可以做压力测试 xff0c 本文介绍手动安装方法 httpd及依赖包安装 以下包因为存在依赖关
  • Cartographer最新版完整安装教程(2020.8.7成功安装)

    2020 8 7更 xff1a 春节之后重装了系统 xff0c 重新安装Cartographer又遇到了困难 xff0c 发现之前的教程naive xff0c 历尽千辛万苦今天终于安装成功 xff0c 而且更加简单方便 xff0c 给大家作
  • 没有可用的软件包××,但是它被其他的软件包引用了——解决方法

    在ubuntu下安装gcc xff1a sudo apt install gcc 谁知这么简单的命令居然不成功 解决方法 xff1a sudo apt get update 待更新完毕后再次输入安装命令即可
  • MapReduce编程之连接Join

    本文笔记整理自 Hadoop海量数据处理 xff1a 技术详解与项目实战 范东来 一 设计思路 HDFS上存放两个文件 xff0c 一个记录了学生基本信息 xff08 姓名 xff0c 学号 xff09 xff0c 文件名 student
  • MapReduce编程之二次排序

    本文笔记整理自 Hadoop海量数据处理 xff1a 技术详解与项目实战 范东来 一 二次排序 二次排序就是先按某一列先进行排序 xff0c 然后在此基础上再对另一列排序 xff08 参看如下表数据 xff09 待排序数据 xff1a 第一
  • 接口测试 之 HTTP 1.1 认证之BASIC认证

    basic认证 介绍认证步骤步骤图解BASIC 认证的的缺点测试 xff1a 认证失败测试 xff1a 认证成功使用postman 如何测试basic认证接口 介绍 BASIC 认证 xff08 基本认证 xff09 是从HTTP 1 1

随机推荐

  • PX4仿真基础

    本文章描述jmavsim和gazebo两种仿真器的使用 仿真器可以让PX4飞行控制程序在仿真的 世界 中控制一架计算机模拟的飞行器 您可以使用QGroundControl地面站程序 API或遥控器与该飞行器进行交互 xff0c 就像与真实飞
  • 在PX4-JMAVSIM软件仿真环境下运行树梅派上的Dronekit飞控应用程序

    苍穹四轴DIY 微信公众号培训教材对Pixhawk飞机加装Raspberry Pi做了介绍 xff0c 关于软件仿真 xff0c 介绍了在Ardupilot飞控系统软件仿真下运行树梅派上的飞控应用程序 xff0c 此文介绍的是在PX4飞控系
  • 在ubuntu上通过编译源代码生成并安装MAVSDK-C++

    版本说明 xff1a ubuntu server 20 0 04 MAVSDK 1 3 1 PX4官网通过编译源代码安装MAVSDK的文章如下 xff1a Building library from Source MAVSDK Guide
  • 在PX4中如何使用offboard模式以及对c_uart_interface_example程序的分析

    c uart interface example是mavlink团队提供的一个演示如何用c语言调用mavlink API对飞机做offboard控制的例子程序 xff0c 这个程序写的挺漂亮的 xff0c 但是 xff0c 新的固件 xff
  • MAVSDK(c++) takeoff_and_land程序分析

    MAVSDK xff08 c 43 43 takeoff and land程序分析 takeoff and land程序是用c 43 43 语言调用MAVSDK API做起飞和降落的控制 MAVSDK xff08 C 43 43 xff09
  • Ubuntu下安装vmware虚拟机软件,vmware上虚拟机的安装、删除

    一直听说虚拟机虚拟机虚拟机 xff0c 关于具体是什么还是不清楚 纸上觉来终觉浅 xff0c 得知此事要躬行 心里的想法千千万 xff0c 只有写下来才能有落地的实感 百科上查找的资料 xff0c 虚拟机 xff08 Virtial Mac
  • 实现Pixhawk 的PX4系统终端

    版本说明 xff1a 1 自驾仪 xff1a Holybro的Pixhawk 4 2 PX4版本 xff1a 1 13 3 宿主机 xff1a Thinkpad笔记本 43 Ubuntu 20 04 2 LTS 参考 xff1a PX4 C
  • QGC开发环境搭建(欢迎交流学习)

    xff10 xff0f 准备好给各位的文件包 xff1a xff11 xff0f 安装QT 链接 xff1a https pan baidu com s 1LvZ7FkDRtHSBFE7YLLBqfw 提取码 xff1a 9kin xff1
  • 四旋翼无人机物理基础

    四旋翼无人机物理基础 1 结构形式2 运动原理 垂直运动 俯仰运动 滚转运动 xff1a 偏航运动 xff1a 前后运动 xff1a 倾向运动 xff1a 1 结构形式 旋翼对称分布在机体的前后 左右四个方向 xff0c 四个旋翼处于同一高
  • npm 清理缓存命令

    npm cache clean f 有些时候npm下载资源出错 xff0c 再次下载的时候可能因为之前错误的缓存造成一直下载不成功 此时可以清一下npm的缓存 xff0c 然后尝试重新下载 使用 可以多清理几次 npm cache clea
  • Taro 和 uni-app选型对比

    Taro 和 uni app选型对比 一 Taro和uni app的介绍 1 taro的介绍 taro是多端统一开发框架 xff0c 支持用 React 的开发方式编写一次代码 xff0c 生成能运行在微信 百度 支付宝 字节跳动小程序 H
  • 小程序 连接websocket 开发者工具上可以,但是真机上不行

    连接websocket 开发者工具上可以 xff0c 但是真机上不行 一定要保证真机和websocket机器在同一个网段 xff1b 基础库 2 4 0 提供了 wx startLocalServiceDiscovery 等一系列 mDNS
  • JS filter()方法 介绍和使用

    filter方法是js中常用的方法 xff1b 一 xff0c 作用 xff1b filter用于对数组进行过滤 它创建一个新数组 xff0c 新数组中的元素是通过检查指定数组中符合条件的所有元素 注意 xff1a filter 不会对空数
  • JS object对象转为array数组

    在开发中经常会遇到接口返回的是对象 xff0c 我们需要转为数组 xff0c 下面提供两种方法 xff1a 第一种方法 xff0c Object values span class token keyword var span data s
  • JS关闭当前页面

    JS关闭当前页面 span class token operator lt span button onclick span class token operator 61 span span class token string 34 C
  • 【马井堂】Js 去掉对象前后空格

    Js 去掉对象前后空格 function emptyParams data const temporary 61 Object assign data for const key in temporary if key if tempora
  • VMware 虚拟机与主机通信三种方式总结

    背景 xff1a ubuntu16 04安装vmware14pro xff0c 开了两台ubuntu12 04的虚拟机 第一台基于NAT方式连接 xff0c 第二台基于Bridged方式连接 主机IP xff1a 192 168 100 1
  • JS 下载-支持多个浏览器(马井堂)

    JS 下载 支持多个浏览器 const downLoadXls 61 fileArrayBuffer filename 61 gt let data 61 new Blob fileArrayBuffer type 39 applicati
  • js微信小程序-版本更新管理器wx.getUpdateManager()、UpdateManager

    js微信小程序 版本更新管理器wx getUpdateManager UpdateManager 1 wx getUpdateManager 官方文档 版本更新管理器wx getUpdateManager 官方文档 wx getUpdate
  • 串口通信+TCP网络通信简单综合实例

    串口通信 43 TCP网络通信简单综合实例 串口通信加上TCP网络通信之后就可以简单实现本地设备的联网功能了 xff0c 哈哈 xff0c 话不多说 xff0c 直接上代码 总体上还是C S模式 xff0c 但是这个客户端加上了对串口的操作