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

2024-3-1-网络编程作业

1>操控机械臂:

通过w(红色臂角度增大)s(红色臂角度减小)
d(蓝色臂角度增大)a(蓝色臂角度减小)按键控制机械臂

源代码:

#include <myhead.h>
#define minStep 10 //最小偏移角度#define SER_IP "10.168.1.116" //服务器ip
#define SER_PORT 8888         //服务器端口号#define CLI_IP "10.168.1.111 " //客户端IP
#define CLI_PORT 9999          //客户端端口号char scanKeyboard();                                          //从键盘获取控制符
void r_angleUp(int fd, char buf[], int buf_size, char skb);   //红色臂向右偏移
void r_angleDown(int fd, char buf[], int buf_size, char skb); //红色臂向左偏移
void b_angleUp(int fd, char buf[], int buf_size, char skb);   //蓝色色臂向右偏移
void b_angleDown(int fd, char buf[], int buf_size, char skb); //蓝色臂向左偏移int main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); //3//2、绑定(非必须)//2.1 填充地址信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CLI_PORT);cin.sin_addr.s_addr = inet_addr(CLI_IP);//2.2 绑定if (bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind success\n");//3、连接服务器//3.1填充要连接的服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;                //地址族sin.sin_port = htons(SER_PORT);          //端口号sin.sin_addr.s_addr = inet_addr(SER_IP); //ip地址//3.2 连接服务器if (connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("connect success\n");//4、数据收发char rbuf[5] = {0xff, 0x02, 0x00, 0x00, 0xff};unsigned char bbuf[5] = {0xff, 0x02, 0x01, 0x00, 0xff};//发送给服务器当做初始值send(cfd, rbuf, sizeof(rbuf), 0);sleep(1);send(cfd, bbuf, sizeof(bbuf), 0);printf("请键入W、S、A、D进行控制:");while (1){char skb = scanKeyboard();if (skb == 27)printf("\n请键入W、S、A、D进行控制(键入Q退出控制!):\n");switch (skb){case 'W':case 'w':{int buf_size1 = sizeof(rbuf);r_angleUp(cfd, rbuf, buf_size1, skb);}break;case 'S':case 's':{int buf_size1 = sizeof(rbuf);r_angleDown(cfd, rbuf, buf_size1, skb);}break;case 'D':case 'd':{int buf_size2 = sizeof(bbuf);b_angleUp(cfd, bbuf, buf_size2, skb);}break;case 'A':case 'a':{int buf_size2 = sizeof(rbuf);b_angleDown(cfd, bbuf, buf_size2, skb);}break;case 'Q':{printf("\n控制已结束\n");return -1;}break;}}//5、关闭套接字close(cfd);return 0;
}char scanKeyboard()
{//终端有三种工作模式:规范模式、非规范模式、原始模式//非规范模式:所有输入时即时有效的,不需要用户另外输入行结束符char in;//定义两个termios结构体变量struct termios new_settings;    //保存用于操作的终端属性struct termios stored_settings; //保存当前的终端属性,以便之后恢复//把标准输入的状态存储在终端配置参数stored_settings中tcgetattr(0, &stored_settings);//把当前终端属性的副本赋值给new_settings,准备对其进行修改。new_settings = stored_settings;//修改new_settings的c_lflag字段,关闭规范模式(ICANON)。//在非规范模式下,输入是即时的,不需要按回车键。new_settings.c_lflag &= (~ICANON);//设置new_settings的VTIME为0。//非规范模式下读取输入时不使用超时。new_settings.c_cc[VTIME] = 0; //非规范模式读取时的超时时间--VTIME//tcgetattr(0, &stored_settings);//在非规范模式下读取输入时至少需要读取1个字符才能返回new_settings.c_cc[VMIN] = 1; //非规范模式读取时的最小字符数--VMIN//将标准输入的属性设置为new_settings,TCSANOW参数指示更改应立即生效,不等待数据传输完成。tcsetattr(0, TCSANOW, &new_settings); //不等数据传输完毕就立即改变属性--TCSANOWin = getchar();//读取完字符后,恢复标准输入的原始属性tcsetattr(0, TCSANOW, &stored_settings);return in;
}void r_angleUp(int fd, char buf[], int buf_size, char skb)
{if (skb != 27) //skb==ECS时退出控制{buf[3] += minStep; //每次操作的角度偏移minStep度if (buf[3] >= 90){buf[3] = 90;}send(fd, buf, buf_size, 0);}return;
}
void r_angleDown(int fd, char buf[], int buf_size, char skb)
{if (skb != 27){buf[3] -= minStep;if (buf[3] <= -90){buf[3] = -90;}send(fd, buf, buf_size, 0);}return;
}
void b_angleUp(int fd, char buf[], int buf_size, char skb)
{if (skb != 27){buf[3] += minStep;if (buf[3] >= 180){buf[3] = 180;}send(fd, buf, buf_size, 0);}return;
}
void b_angleDown(int fd, char buf[], int buf_size, char skb)
{if (skb != 27){buf[3] -= minStep;if (buf[3] <= 0){buf[3] = 0;}send(fd, buf, buf_size, 0);}return;
}

效果展示:

机械臂演示

2>基于UDP的TFTP文件传输

源代码:

#include <myhead.h>
#define SER_IP "10.168.1.116"
#define SER_PORT 69
#define MAXSIZE 1024
#define FILESIZE 128
enum mode_opt
{READ = 1,WRITE = 2,DATA = 3,ACK = 4,ERR = 5
};void request_WR(char pack[], int pack_size, char *name, int mode, int *packlen)
{bzero(pack, pack_size);char *p = pack;short int *p1 = (short int *)p;*p1 = htons(mode);           //设置操作码char *p2 = (char *)(p1 + 1); //**********strcpy(p2, name);            //文件名char *p4 = p2 + strlen(p2) + 1;strcpy(p4, "octet");                    //模式位*packlen = 4 + strlen(p2) + strlen(p4); //请求包的大小
}int download(int cfd, struct sockaddr_in sin, char *name)
{char pack[MAXSIZE] = "";int packlen = 0;//组件协议包:下载请求request_WR(pack, sizeof(pack), name, READ, &packlen);sendto(cfd, pack, packlen, 0, (struct sockaddr *)&sin, sizeof(sin));int rcvlen = 0;int fd = -1;if ((fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1){perror("open error");close(fd);return -1;}//添加了对块编号的检查和管理unsigned short expected_block_num = 1;char data[MAXSIZE] = "";socklen_t socklen = sizeof(sin);while (1){//收取服务器发来的数据包rcvlen = recvfrom(cfd, data, sizeof(data), 0, (struct sockaddr *)&sin, &socklen);if (rcvlen == -1){perror("recv error");return -1;}short int *p1_data = (short int *)data;short code = ntohs(*p1_data);short block_num = ntohs(*(p1_data + 1));if (code == DATA){if (block_num == expected_block_num) //只有当接收到的数据包的块编号符合预期时,才会写入文件并发送ACK{write(fd, data + 4, rcvlen - 4);char ack[4];*(short *)ack = htons(ACK);*(short *)(ack + 2) = htons(block_num); // 确认收到的块编号sendto(cfd, ack, 4, 0, (struct sockaddr *)&sin, sizeof(sin));if (rcvlen < 516) // 如果接收到的数据包小于516字节,表示是最后一个数据包{printf("下载完成\n");break;}expected_block_num++;}}else if (code == ERR){printf("ERROR:%d\n", block_num); // block_num在这里作为错误码close(fd);return -1; // 返回错误码}}close(fd);return 0;
}
int upload(int cfd, struct sockaddr_in sin, char *name)
{char packet[MAXSIZE] = "";int packlen = 0;request_WR(packet, sizeof(packet), name, WRITE, &packlen);sendto(cfd, packet, packlen, 0, (struct sockaddr *)&sin, sizeof(sin));int fd = -1;if ((fd = open(name, O_RDONLY)) == -1){perror("open error");return -1;}char buf[MAXSIZE] = "";socklen_t socklen = sizeof(sin);int rcvlen = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &socklen);short int *p1_data = (short int *)buf;提取ACK的操作码short code = ntohs(*p1_data);//提取ACK的块编号unsigned short block_num = ntohs(*(p1_data + 1));if (code != ACK || block_num != 0){printf(" ACK  or block error\n");close(fd);return -1;}unsigned short send_block_num = 1; // 设置发送数据包的块编号while (1){bzero(buf, sizeof(buf));int num = read(fd, buf + 4, 512);if (num < 0){perror("read error");close(fd);return -1;}// 构造数据包头部(操作码和块编号)*(short *)packet = htons(DATA);                 // 设置操作码为DATA*(short *)(packet + 2) = htons(send_block_num); // 设置数据块编号memcpy(packet + 4, buf + 4, num);               // 复制文件数据到数据包// 发送数据包sendto(cfd, packet, num + 4, 0, (struct sockaddr *)&sin, socklen);// 等待ACKrcvlen = recvfrom(cfd, buf, 4, 0, (struct sockaddr *)&sin, &socklen);if (rcvlen < 4){perror("recv ACK error");close(fd);return -1;}p1_data = (short int *)buf;code = ntohs(*p1_data);            // 提取操作码block_num = ntohs(*(p1_data + 1)); // 提取块编号// 检查ACK的块编号是否与发送的数据包匹配if (code != ACK || block_num != send_block_num){printf("ACK  or block error\n");close(fd);return -1;}if (num < 512) // 如果读取的数据小于512字节,表示文件已经发送完毕{printf("上传完毕\n");break;}send_block_num++; // 准备下一个数据块的编号}close(fd);return 0;
}
int main(int argc, char const *argv[])
{printf("\t\t*************************\n");printf("\t\t*********1.下载**********\n");printf("\t\t*********2.上传**********\n");printf("\t\t*********3.退出**********\n");printf("\t\t*************************\n");if (argc < 2){printf("请输入IP\n");return -1;}int choice;scanf("%d", &choice);getchar();char name[FILESIZE];int cfd = socket(AF_INET, SOCK_DGRAM, 0);int reuse = 1;if (setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);socklen_t socklen = sizeof(sin);switch (choice){case 1:{printf("输入下载的文件:");scanf("%s", name);download(cfd, sin, name);}break;case 2:{printf("输入上传的文件:");scanf("%s", name);upload(cfd, sin, name);}break;case 3:{return 0;}break;default:{printf("error choice\n");}break;}close(cfd);return 0;
}

效果展示:

TFTP

相关文章:

2024-3-1-网络编程作业

1>操控机械臂&#xff1a; 通过w(红色臂角度增大)s&#xff08;红色臂角度减小&#xff09; d&#xff08;蓝色臂角度增大&#xff09;a&#xff08;蓝色臂角度减小&#xff09;按键控制机械臂 源代码&#xff1a; #include <myhead.h> #define minStep 10 //最小偏…...

pytorch基础2-数据集与归一化

专题链接&#xff1a;https://blog.csdn.net/qq_33345365/category_12591348.html 本教程翻译自微软教程&#xff1a;https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次编辑&#xff1a;2024/3/2&#xff1b;最后编辑&#xff1a;2024/3/2 本教程…...

Python测试框架pytest介绍用法

1、介绍 pytest是python的一种单元测试框架&#xff0c;同自带的unittest测试框架类似&#xff0c;相比于unittest框架使用起来更简洁、效率更高 pip install -U pytest 特点&#xff1a; 1.非常容易上手,入门简单,文档丰富&#xff0c;文档中有很多实例可以参考 2.支持简单的单…...

AI对话系统app开源

支持对接gpt&#xff0c;阿里云&#xff0c;腾讯云 具体看截图 后端环境&#xff1a;PHP7.4MySQL5.6 软件&#xff1a;uniapp 废话不多说直接上抗揍云链接&#xff1a; https://mny.lanzout.com/iKFRY1o1zusf 部署教程请看源码内的【使用教程】文档 欢迎各位转载该帖/源码...

SpringBoot+aop实现主从数据库的读写分离

读写分离的作用是为了缓解写库&#xff0c;也就是主库的压力&#xff0c;但一定要基于数据一致性的原则&#xff0c;就是保证主从库之间的数据一定要一致。如果一个方法涉及到写的逻辑&#xff0c;那么该方法里所有的数据库操作都要走主库。 一、环境部署 数据库&#xff1a;…...

胎神游戏集第二期

延续上一期 一、海岛奇胎 #include<bits/stdc.h> #include<windows.h> #include<stdio.h> #include<conio.h> #include<time.h> using namespace std; typedef BOOL (WINAPI *PROCSETCONSOLEFONT)(HANDLE, DWORD); PROCSETCONSOLEFONT SetCons…...

Unicode/ASCII/UTF的关系(模板字面量、模板字符串、占位符)

字符串&#xff1a;编程时最重要的数据类型之一。 正则表达式&#xff1a;赋予开发者更多操作字符串的能力。 1、 Unicode和ASCII 1.1 概述 Unicode是ASCII字符编码的一个扩展&#xff0c;只不过在Windows中&#xff0c;用两个字节对其进行编码&#xff0c;也称为宽字符集&…...

三、低代码平台-单据配置(单表增删改查)

一、业务效果图 主界面 二、配置过程简介 配置流程&#xff1a;业务表设计 -》业务对象建立-》业务单据配置-》菜单配置。 a、业务表设计 b、业务对象建立 c、业务单据配置 功能路径&#xff1a;低代码开发平台/业务开发配置/单据配置维护 d、菜单配置...

6.1 数据驱动型业务管理方法(3%)

1 数据的产生与应用 1.数据的产生 2.数据的特征 3.数据的应用过程 应用到决策过程中 4.从决策到执行 决策&#xff1a;靠经验来进行决策&#xff08;80%&#xff09;&#xff1b;可依据数据辅助&#xff08;20%&#xff09; 经验比数据重要的多&#xff0c;数据是辅助&…...

JVM学习目录

JVM ✅ JVM运行时内存结构 ✅ JVM常用启动参数 ✅ JVM内存分配与垃圾收集流程 ✅ 什么是垃圾回收机制&#xff08;Garbage Collection&#xff0c;简称GC&#xff09; ✅ 如何调用垃圾回收器的方法 ✅ GC如何判定对象已死 ✅ 方法区的垃圾收集 ✅ 垃圾收集算法 ✅ JVM垃圾回…...

使用远程桌面连接工具上传文件到Windows轻量应用服务器时,如何优化文件传输速度?

使用远程桌面连接工具上传文件到Windows轻量应用服务器时&#xff0c;如何优化文件传输速度&#xff1f; 优化网络连接&#xff1a;确保网络连接稳定和畅通&#xff0c;使用有线网络连接代替无线网络&#xff0c;以减少网络延迟和提高文件传输速度。 调整远程桌面设置&#xf…...

【Linux】基本指令(下)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:Linux ⚙️操作环境:Xshell (操作系统:CentOS 7.9 64位) 日志 日志的概念: 网络设备、系统及服务程序等&#xff0c;在运作时都会产生一个叫log的事件记录&#xff1b;每一行日志都记载着日期、时间、使用者及动作等相关…...

LeetCode受限条件下可到达节点的数目

题目描述 现有一棵由 n 个节点组成的无向树&#xff0c;节点编号从 0 到 n - 1 &#xff0c;共有 n - 1 条边。 给你一个二维整数数组 edges &#xff0c;长度为 n - 1 &#xff0c;其中 edges[i] [ai, bi] 表示树中节点 ai 和 bi 之间存在一条边。另给你一个整数数组 restr…...

[Flutter]设置应用包名、名称、版本号、最低支持版本、Icon、启动页以及环境判断、平台判断和打包

一、设置应用包名 在Flutter开发中&#xff0c;修改应用程序的包名&#xff08;也称作Application ID&#xff09;涉及几个步骤&#xff0c;因为包名是在项目的Android和iOS平台代码中分别配置的。请按照以下步骤操作&#xff1a; 1.Android Flutter工程中全局搜索替换包名 …...

electron-release-server部署electron自动更新服务器记录

目录 一、前言 环境 二、步骤 1、下载上传electron-release-server到服务器 2、宝塔新建node项目网站 3、安装依赖 ①npm install ②安装并配置postgres数据库 ③修改项目配置文件 ④启动项目 ⑤修改postgres的认证方式 ⑥Cannot find where you keep your Bower p…...

贪心(基础算法)--- 区间选点

905. 区间选点 思路 &#xff08;贪心&#xff09;O(nlogn) 根据右端点排序 将区间按右端点排序 遍历区间&#xff0c;如果当前区间左端点不包含在前一个区间中&#xff0c;则选取新区间&#xff0c;所选点个数加1&#xff0c;更新当前区间右端点。如果包含&#xff0c;则跳…...

JAVA计算表达式

需求&#xff1a; 1、例如if(score>85){return 1;}else if(score>70){return 2;}else if(score>60){return 3;}else{return 4;}有这一串字符串&#xff0c;要执行这个字符串&#xff0c; 如果score为86分&#xff0c;则能得到1&#xff1b;如果score为30分&#xff…...

【复现】宏景HCM 任意文件读取漏洞_63

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 宏景HCM 将人才标签技术应用于员工招聘、人才选拔等环节&#xff0c;通过多维度的标签体系&#xff0c;形成不同专业序列的人才画…...

Linux:kubernetes(k8s)搭建mater节点(kubeadm,kubectl,kubelet)(2)

安装k8有多种方式如&#xff1a; minikube kubeadm 二进制安装 命令行工具 我这里就使用kubeadm进行安装 环境 3台centos7 master ip &#xff1a;192.168.113.120 2G运存 2内核 node1 ip &#xff1a;192.168.113.121 2G运存 2内核 node2 ip &#xff1a;192.168.1…...

Web应用安全威胁与防护措施

本文已收录至《全国计算机等级考试——信息 安全技术》专栏 由于极其容易出现漏洞、并引发安全事故&#xff0c;因此数据隐私的保护是目前绝大多数企业不可绕过的运维环节。不过&#xff0c;许多中小型企业往往会错误地认为只有大型企业才会成为黑客的目标。而实际统计数字却截…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...