小工具知识网

当前位置: 首页 > 行业知识 > 41、网络编程/TCP.UDP通信模型练习20240301

行业知识

41、网络编程/TCP.UDP通信模型练习20240301

2026-11-06 15:10:52 来源:互联网转载

一、���写基于TCP的客户端实现以下功能:

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

1.基于TCP服务器的机械臂,端口号是8888, ip是Windows的ip;

查看Windows的IP:按住Windows+r 按键,输入cmd , 输入ipconfig。

2.点击软件中的开启监听;

3.机械臂需要发送16进制数,共5个字节,协议如下

0xff    0x02    x   y   0xff0xff:起始结束协议,固定的;0x02:控制机械手臂协议,固定的;x:指定要操作的机械臂    0x00 红色摆臂    0x01 蓝色摆臂y:指定角度

代码:

#include#define SER_IP "192.168.125.64"  //服务器IP#define SER_PORT 8888          //服务器端口号int main(int argc, const char *argv[]){//创建套接字文件int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -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);//连接服务器if(connect(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("connect error");return -1;}puts("connect success");//数据发送//定义控制红色臂的数组并初始化,范围是[-90,90]char rbuf[5]={0xff,0x02,0x00,0x00,0xff};//定义控制蓝色臂的数组并初始化,范围是[0,180]unsigned char bbuf[5]={0xff,0x02,0x01,0x00,0xff};//发送初始值send(sfd,rbuf,sizeof(rbuf),0);sleep(1);//防止沾包send(sfd,bbuf,sizeof(bbuf),0);char key=0;while(1){system("stty -icanon");//关闭缓冲区key=getchar();fflush(stdin);switch(key){case 'W':case 'w':{rbuf[3]+=2;//每次操作的角度偏移2度if(rbuf[3]>=90){rbuf[3]=90;}send(sfd,rbuf,sizeof(rbuf),0);}break;case 'S':case 's':{rbuf[3]-=2;if(rbuf[3]=180){bbuf[3]=180;}send(sfd,bbuf,sizeof(bbuf),0);}break;case 'A':case 'a':{bbuf[3]-=2;if(bbuf[3]>180)//无符号整数小于零后会向255循环{bbuf[3]=0;}send(sfd,bbuf,sizeof(bbuf),0);}break;}}close(sfd);return 0;}

运行:

思维导图

二、 基于UDP的TFTP文件传输

1.tftp协议概述

简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输

特点:

是应用层协议

基于UDP协议实现

数据传输模式

octet:二进制模式(常用)

mail:已经不再支持

2.tftp下载模型

TFTP通信过程总结

  1. 服务器在69号端口等待客户端的请求
  2. 服务器若批准此请求,则使用 临时端口 与客户端进行通信。
  3. 每个数据包的编号都有变化(从1开始)
  4. 每个数据包都要得到ACK的确认,如果出现超时,则需要重新发送最后的数据包或ACK包
  5. 数据长度以512Byte传输的,小于512Byte的数据意味着数据传输结束。

差错码:

0 未定义,差错错误信息

1 File not found.

2 Access violation.

3 Disk full or allocation exceeded.

4 illegal TFTP operation.

5 Unknown transfer ID.

6 File already exists.

7 No such user.

8 Unsupported option(s) requested.

代码:

#include#define SER_IP "192.168.125.57"#define SER_POTR 69int my_download(int cfd,struct sockaddr_in sin);int my_upload(int cfd,struct sockaddr_in sin);int my_save_data(char *p,int len);int recv_ack(char *pack,int res);int main(int argc, const char *argv[]){//创建通信套接字int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd==-1){perror("socket error");return -1;}//定义地址结构体 保存客户端地址struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_POTR);sin.sin_addr.s_addr=inet_addr(SER_IP);int menu=0;while(1){system("clear");puts("\t\t------请选择选项------");printf("\t\t-------1.上传-------\n");printf("\t\t-------2.下载-------\n");printf("\t\t-------0.退出-------\n");scanf("%d",&menu);getchar();switch(menu){case 0:goto END;case 1:   {   int res=my_upload(cfd,sin);   if(res==-1)   {   puts("my_upload error");   return -1;   }   }break;case 2:   {   int res=my_download(cfd,sin);   if(res==-1)   {   puts("my_download error");   return -1;   }   }break;default:   {   puts("输入有误,请重新输入");   }break;}puts("请输入任意键按回车结束!");while(getchar()!='\n');}END:close(cfd);return 0;}int my_download(int cfd,struct sockaddr_in sin){//定义收发数据容器char pack[516]="";//组建请求协议包//1.请求下载printf("请输入要下载的文件名:");char txt[32]="";fgets(txt,sizeof(txt),stdin);txt[strlen(txt)-1]=0;short *p1=(short*)pack;*p1=htons(1);//存入前两字节的操作码1代表读(下载)char *p2=pack+2;strcpy(p2,txt);//存入文件名及结尾的0char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");//存入模式位及结尾的0int packlen=4+strlen(p2)+strlen(p3);//发送下载请求if(sendto(cfd,pack,packlen,0,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("download request sendto error");return -1;}/*//读取服务器的回复消息int ack=recv_ack(cfd,sin);if(ack==-1){puts("recv_ack error");return -1;}*/while(1){bzero(pack,sizeof(pack));int sinlen=sizeof(sin);int res=-1;if((res=(recvfrom(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,&sinlen)))==-1){perror("my_download recvfrom error");return -1;}int ack=recv_ack(pack,res);if(ack==-1){puts("my_download recv_ack error");return -1;}*p1=htons(4);//设置ACK包*(p1+1)=htons(ack);//如果读取的长度小于516说明已经下载完成if(res

上一篇:宝塔面板密钥查看指南,轻松掌握密钥管理技巧!

下一篇:Spring Cloud Gateway 过滤器详解