当前位置: 首页 > news >正文

WSL和Windows建立TCP通信协议

1.windows配置

首先是windows端,启动TCP服务端,用来监听指定的端口号,其中IP地址可以设置为任意,否则服务器可能无法正常打开。

addrSer.sin_addr.S_un.S_addr = INADDR_ANY;

recv函数用来接收客户端传输的数据,其中sum表示接收到的字节数。

为了能将接收到的char数据转换成16进制形式,方便与发送数据进行比对。

rece = ToHexString((unsigned char*)recvbuf, sum);

这里sum不能替换为strlen(recvbuf),strlen在检测到"00"后会自动结束,打印的数据不全。

string ToHexString(unsigned char* input, int datasize)
{stringstream ss;ss << setbase(16) << setfill('0');for (int i = 0; i < datasize; i++)ss << setw(2) << (UINT)input[i];return ss.str();
}

TCP接收到的不是一个一个的数据,而是一段一段的数据,中间可能包含着多条信息,需要根据起始位将信息提取出来。

vector<int> positions = findAllSubstringPositions(rece, "aaa55a");
vector<string> s;
if(positions.size()>0){s.push_back(rece.substr(0, positions[0] + 2));for (int i = 1; i < positions.size(); i++) {cout << positions[i - 1] << endl;s.push_back(rece.substr(positions[i-1] + 2, positions[i]- positions[i - 1]));}s.push_back(rece.substr(positions[positions.size()-1]+2));
}
else {s.push_back(rece);
}
for(int j=0;j<= positions.size();j++)cout << s[j] << endl;

这里由于不知道一段包含命令的个数,所以用vector容器来存放比较合适,同时substr第一个参数是起始位置,第二个参数是需要提取字符串的长度,不是终止位置。

2.WSL配置

WSL作客户端,用来监听串口数据并返还给服务端。

第一步:让WSL可以检测到USB

powershell输入usbipd list查看当前USB设备(电脑间测试需要串口盒辅助,另外一台电脑打开串口调试助手,向WSL发送十六进制数据)

usbipd bind --busid 1-6   共享串口

usbipd attach --wsl -b 1-6   附加USB设备到WSL上

WSL输入lsusb检测当前USB设备

ls /dev/tty*查看USB设备的端口号

第二步:WSL开启串口监听

根据查询到的端口号配置端口

    //listen uartfd1 = open( "/dev/ttyS9", O_RDWR);if (fd1 == -1) {printf("open error!\n");}int nset = set_opt(fd1, 115200, 8, 'N', 1);if (nset == -1) {printf("set error!\n");}

第三步:配置接收线程

主函数开启线程std::thread uart(uart_read);

while(1)循环里连续接收n = read(fd1, send_buf, UART_BUFF);

n表示接收到的字符串长度,这里read可能会分段接收,加入起始位和长度的判断

        if(n>0){if(n>2){if(ToHexString((unsigned char*)send_buf,2) == "a55a"){flag=1;count=0;memset(rece_buf,'\0',UART_BUFF);numchar = (unsigned char)send_buf[2];sum = (int)numchar;}}if(flag){for(int i=count;i<(count+n);i++){rece_buf[i] = send_buf[i-count];}count += n;if(sum == (count-2)){cout << ToHexString((unsigned char*)rece_buf,sum+2) << endl;len=send(client_sockfd, rece_buf, count, 0);//TCP客户端发送count = 0;}else if(sum < (count-2)){flag = 0;count = 0;}}}

这里数据的长度为unsigned char类型,用int强转

count表示接收到的字符串长度,其中rece_buf不能使用strcat来进行拼接,还是"00"的问题。

第四步:文件编译

一般的文件编译使用gcc -o 工程名 工程文件的格式

而std::thread则要

g++ -o 工程名 工程文件名 -lpthread -std=c++11

执行:

        ./工程名

完整代码

#include<iostream>
#include<cstring>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <termios.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <thread>
#include <time.h>
#include <exception>
#include <syslog.h>
#include <stdlib.h>
#include <sstream>
#include <iomanip>
#include <string>using namespace std;
typedef unsigned int UINT;
#define UART_BUFF 2048int client_sockfd;
int len;
int fd1=-1;string ToHexString(unsigned char* input, int datasize)
{stringstream ss;ss << setbase(16) << setfill('0');for (int i = 0; i < datasize; i++)ss << setw(2) << (UINT)input[i];return ss.str();
}int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{struct termios newtio,oldtio;if  ( tcgetattr( fd,&oldtio)  !=  0){perror("SetupSerial 1");return -1;}bzero( &newtio, sizeof( newtio ) );newtio.c_cflag  |=  CLOCAL | CREAD;newtio.c_cflag &= ~CSIZE;switch( nBits ){case 7:newtio.c_cflag |= CS7;break;case 8:newtio.c_cflag |= CS8;break;}switch( nEvent ){case 'O':newtio.c_cflag |= PARENB;newtio.c_cflag |= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);break;case 'E':newtio.c_iflag |= (INPCK | ISTRIP);newtio.c_cflag |= PARENB;newtio.c_cflag &= ~PARODD;break;case 'N':newtio.c_cflag &= ~PARENB;break;}switch( nSpeed ){case 2400:cfsetispeed(&newtio, B2400);cfsetospeed(&newtio, B2400);break;case 4800:cfsetispeed(&newtio, B4800);cfsetospeed(&newtio, B4800);break;case 9600:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;case 115200:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;case 460800:cfsetispeed(&newtio, B460800);cfsetospeed(&newtio, B460800);break;default:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;}if( nStop == 1 )newtio.c_cflag &=  ~CSTOPB; else if ( nStop == 2 )newtio.c_cflag |=  CSTOPB;newtio.c_cc[VTIME]  = 0;newtio.c_cc[VMIN] = 0;tcflush(fd,TCIFLUSH);if((tcsetattr(fd,TCSANOW,&newtio))!=0){perror("com set error");return -1;}return 0;
}void uart_read(){char send_buf[UART_BUFF];int flag=0;int sum=0,count=0;char rece_buf[UART_BUFF];char send_buf_use[UART_BUFF];string numStr;unsigned char numchar;int n;while(1){n = read(fd1, send_buf, UART_BUFF);//cout << n << endl;if(n>0){if(n>2){if(ToHexString((unsigned char*)send_buf,2) == "a55a"){flag=1;count=0;memset(rece_buf,'\0',UART_BUFF);numchar = (unsigned char)send_buf[2];sum = (int)numchar;// cout << ToHexString((unsigned char*)send_buf,n) << "***" << endl;}}if(flag){cout << ToHexString((unsigned char*)send_buf,n) << "***" << endl;for(int i=count;i<(count+n);i++){rece_buf[i] = send_buf[i-count];}count += n;//cout << ToHexString((unsigned char*)rece_buf,count) << endl;if(sum == (count-2)){cout << ToHexString((unsigned char*)rece_buf,sum+2) << endl;len=send(client_sockfd, rece_buf, count, 0);count = 0;}else if(sum < (count-2)){flag = 0;count = 0;}}}//else//usleep(5000);}return;	
}int main()
{struct sockaddr_in remote_addr;char recv_buf[UART_BUFF];char send_buf[UART_BUFF];memset(&remote_addr, 0, sizeof(remote_addr));remote_addr.sin_family=AF_INET;remote_addr.sin_addr.s_addr=inet_addr("192.168.192.100");remote_addr.sin_port=htons(6666);//listen uartfd1 = open( "/dev/ttyS9", O_RDWR);if (fd1 == -1) {printf("open error!\n");}int nset = set_opt(fd1, 115200, 8, 'N', 1);if (nset == -1) {printf("set error!\n");}//IPv4 tcpif((client_sockfd=socket(PF_INET, SOCK_STREAM, 0))<0){cout<<"socket error";return 1;}if(connect(client_sockfd, (struct sockaddr*)&remote_addr, sizeof(struct sockaddr))<0){cout<<"connect error";return 1;} cout<<"connected to server"<<endl;std::thread uart(uart_read);while(1){usleep(100);}uart.join();close(client_sockfd);close(fd1);return 0;
}

相关文章:

WSL和Windows建立TCP通信协议

1.windows配置 首先是windows端&#xff0c;启动TCP服务端&#xff0c;用来监听指定的端口号&#xff0c;其中IP地址可以设置为任意&#xff0c;否则服务器可能无法正常打开。 addrSer.sin_addr.S_un.S_addr INADDR_ANY; recv函数用来接收客户端传输的数据&#xff0c;其中…...

Android Gradle开发与应用(一):Gradle基础

文章目录 引言一、Gradle简介二、Gradle基础语法1. 项目结构2. 插件应用3. 仓库与依赖4. 任务&#xff08;Tasks&#xff09; 三、Gradle在Android项目中的深入应用1. 构建变体&#xff08;Build Variants&#xff09;2. 依赖管理3. 自定义构建逻辑 四、Gradle WrapperGradle W…...

Linux多线程服务器编程-1-线程安全的对象生命期管理

对象的生与死不能由对象自身拥有的mutex&#xff08;互斥器&#xff09;来保护. 如何避免对象析构时可能存在的race condi​t​ion&#xff08;竞态条件&#xff09;是C多线程编程面临的基本问题。 对象的销毁可能出现多种竞态条件(race condi​t​ion)&#xff1a; 在即将析构…...

Couchbase 技术详解

文章目录 Couchbase 原理数据模型数据分布数据访问与同步官网链接 基础使用安装与配置数据操作 高级使用数据分片与负载均衡数据索引与查询安全性与权限管理 优点高性能可扩展性高可用性灵活性 总结 Couchbase 是一个高性能、分布式、可扩展的 NoSQL 数据库系统&#xff0c;基于…...

PTE-信息收集

一、渗透测试流程 渗透测试通常遵循以下六个基本步骤&#xff1a; 前期交互&#xff1a;与客户沟通&#xff0c;明确测试范围、目标、规则等。信息收集&#xff1a;搜集目标系统的相关信息。威胁建模&#xff1a;分析目标系统可能存在的安全威胁。漏洞分析&#xff1a;对收集…...

委外订单执行明细表增加二开字段

文章目录 委外订单执行明细表增加二开字段业务背景业务需求方案设计详细设计扩展《委外订单执行明细表》扩展《委外订单执行明细过滤》创建插件&#xff0c;并实现报表逻辑修改创建插件&#xff0c;添加引用创建类&#xff0c;继承原数据源类ROExecuteDetailRpt报表挂载插件 委…...

“数字孪生+大模型“:打造设施农业全场景数字化运营新范式

设施农业是一个高度复杂和精细化管理的行业,涉及环境控制、作物生长、病虫害防治、灌溉施肥等诸多环节。传统的人工管理模式已经难以应对日益增长的市场需求和管理挑战。智慧农业的兴起为设施农业带来了新的机遇。将前沿信息技术与农业生产深度融合,实现农业生产的数字化、网络…...

zeppline 连接flink 1.17报错

Caused by: java.io.IOException: More than 1 flink scala jar files: /BigData/run/zeppelin/interpreter/flink/zeppelin-flink-0.11.1-2.12.jar,/BigData/run/zeppelin/interpreter/flink/._zeppelin-flink-0.11.1-2.12.jar 解决方案&#xff1a; 重新编译zepplin代码&…...

【机器视觉】【目标检测】【面试】独家问题总结表格

简述anchor free和anchor boxanchor free是对gt实际的左上和右下的点做回归,anchor box是对辅助框即锚框做回归说说对锚框的理解锚框是辅助框, 可以通过预设的长宽比设定,也可以通过k-means算法聚类数据集得到目标检测的指标MAP,FLOPS,FPS,参数量简述非极大值抑制(NMS)非极大…...

从零开始,快速打造API:揭秘 Python 库toapi的神奇力量

在开发过程中&#xff0c;我们常常需要从不同的网站获取数据&#xff0c;有时候还需要将这些数据转化成API接口提供给前端使用。传统的方法可能需要大量的时间和精力去编写代码。但今天我要介绍一个神奇的Python库——toapi&#xff0c;它可以让你在几分钟内创建API接口&#x…...

如何理解复信号z的傅里叶变换在频率v<0的时候恒为0,是解析信号

考虑例子2.12.1的说法。 首先我尝试解释第二个说法。需要注意一个事实是 实函数f的傅里叶变换F的实部是偶函数&#xff0c;虚部是奇函数。如图所示&#xff1a; 注意的是这个图中虽然是离散傅里叶变换的性质&#xff0c;但是对于一般的傅里叶变换的性质是适用的。 推导过程如下…...

大型赛事5G室内无线网络保障方案

大型活动往往才是国家综合实力的重要体现&#xff0c;其无线网络通信保障工作需融合各类新兴的5G业务应用&#xff0c;是一项技术难度高、方案复杂度高的系统工程。尤其在活动人员复杂、现场突发情况多、网络不稳定等情况下&#xff0c;如何形成一套高效、稳定的应急通信解决方…...

windows 2012域服务SYSVOL复制异常

这边文章是我多年前在BBS提问的&#xff0c;后来有高手回答&#xff0c;我把他保存了下来&#xff0c;最近服务器出现问题&#xff0c;终于有翻出来了&#xff01;发出来希望能帮到更多人。 问题 我的环境&#xff0c;windows 2012。最近改了一些域策略&#xff0c;发现没有正…...

动态规划,蒙特卡洛,TD,Qlearing,Sars,DQN,REINFORCE算法对比

动态规划&#xff08;Dynamic Programming, DP&#xff09;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划的步骤 识别子问题&#xff1a;定义问题的递归解法&#xff0c;识别状态和选择。确定DP数组&#xff1a;确定存储子问题解的数据结构&#xff…...

HarmonyOS开发商城商品详情页

目录 一:功能概述 二:代码实现 三:效果图 一:功能概述 这一节,我们实现商品详情页的开发,具体流程就是在首页的商品列表点击商品跳转到商品详情页面,同时传递参数到该页面,通过参数调用商品详情接口在详情页展示商品的的详情信息。这里我们为了方便返回首页,在最顶…...

OS_操作系统的运行环境

2024.06.11:操作系统的运行环境学习笔记 第3节 操作系统的运行环境 3.1 操作系统引导3.2 操作系统内核3.2.1 内核资源管理3.2.2 内核基本功能 3.3 CPU的双重工作模式3.3.1 CPU处于用户态&#xff08;目态&#xff09;3.3.2 CPU处于内核态&#xff08;管态&#xff09; 3.4 特权…...

Maven下载和安装(详细版)

前言 Maven 的含义 Maven 是一个 java 项目管理 和构建工具&#xff0c;他可以定义项目结构&#xff0c;项目依托&#xff0c;并使用统一的方式进行自动化构建&#xff0c;是 java项目不可或缺的工具。 Maven 的 优点 1 提供 标准化的项目结构&#xff08;具体规定了文件的…...

【优秀python大屏案例】基于python flask的前程无忧大数据岗位分析可视化大屏设计与实现

随着大数据和人工智能技术的迅猛发展&#xff0c;数据分析和可视化在各个行业中的应用越来越广泛。特别是在招聘领域&#xff0c;大数据分析不仅能够帮助企业更好地了解市场需求&#xff0c;还能为求职者提供科学的职业规划建议。本文探讨了基于Python Flask框架的前程无忧大数…...

简单的docker学习 第3章docker镜像

第3章 Docker 镜像 3.1镜像基础 3.1.1 镜像简介 ​ 镜像是一种轻量级、可执行的独立软件包&#xff0c;也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境。具体来说镜像包含运行某个软件所需的所有内容&#xff0c;包括代码、库、环境变量和配置文件等…...

jquery.ajax + antd.Upload.customRequest文件上传进度

前情提要&#xff1a;大文件分片上传&#xff0c;需要利用Upload的customRequest属性自定义上传方法。也就是无法通过给Upload的action属性赋值上传地址进行上传&#xff0c;所以Upload组件自带的上传进度条&#xff0c;也没法直接用了&#xff0c;需要在customRequest中加工一…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

算法刷题-回溯

今天给大家分享的还是一道关于dfs回溯的问题&#xff0c;对于这类问题大家还是要多刷和总结&#xff0c;总体难度还是偏大。 对于回溯问题有几个关键点&#xff1a; 1.首先对于这类回溯可以节点可以随机选择的问题&#xff0c;要做mian函数中循环调用dfs&#xff08;i&#x…...