1.思维导图
2.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 0xff
0xff:起始结束协议,固定的
0x02:控制机械手臂协议,固定的
x:指定要操作的机械臂
0x00:红色摆臂
0x01:蓝色摆臂
y:指定角度
tcpCli.c
#include<myhead.h>
#define SER_IP "192.168.125.162" //服务器IP
#define SER_PORT 7777 //服务器端口#define CLI_IP "192.168.159.144" //客户端IP
#define CLI_PORT 9999 //客户端端口号int main(int argc, const char *argv[])
{//1.创建用于通信的套接字文件描述符int cfd=-1;cfd=socket(AF_INET,SOCK_STREAM,0);//参数1:表示使用的是IPv4的通信协议//参数2:表示使用tcp通信类型//参数3:表示前面已经特定了通信协议if(cfd==-1){perror("socket error");return -1;}printf("cfd=%d\n",cfd);//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);char key=0; //接收键盘输入的字符while(1){scanf("%c",&key); //键盘输入一个字符getchar(); //吸收回车switch(key){case 'W':case 'w':{rbuf[3]+=5; //每次操作的角度偏移5度if(rbuf[3]>=90){rbuf[3]=90;}send(cfd,rbuf,sizeof(rbuf),0);}break;case 'S':case 's':{rbuf[3]-=5; //每次操作的角度偏移5度if(rbuf[3]<=-90){rbuf[3]=-90;}send(cfd,rbuf,sizeof(rbuf),0);}break;case 'D':case 'd':{bbuf[3]+=5; //每次操作的角度偏移5度if(bbuf[3]>=180){bbuf[3]=180;}send(cfd,bbuf,sizeof(bbuf),0);}break;case 'A':case 'a':{bbuf[3]-=5; //每次操作的角度偏移5度if(bbuf[3]<=0){bbuf[3]=0;}send(cfd,bbuf,sizeof(bbuf),0);}break;}}//6.关闭套接字close(cfd);return 0;
}
3.基于UDP的TFTP文件传输
1)TFTP协议概述
简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输
特点:是应用层协议
基于UDP协议实现
数据传输模式:octet:二进制模式
mail:已经不再支持
2)TFTP下载模型
TFTP通信过程总结:
1.服务器在69端口等待客户端的请求
2.服务器若批准此请求,则使用临时端口与客户端进行通信
3.每个数据包的编号都有变化(从1开始)
4.每个数据包都要得到ACK的确认,如果出现超时则需要重新发送最后的数据包或ACK包
5.数据长度以512Byte传输的,小于512Byte的数据意味着数据传输结束
3)TFTP协议分析
#include<myhead.h>
#define SER_IP "192.168.125.162"
#define SER_PORT 69
int communication();
int file_upload();
int file_download();
int main(int argc, const char *argv[])
{int menu=0;while(1){system("clear"); //执行终端指令printf("\t\t=====TFTP菜单界面=====\n");printf("\t\t=====1.下载===========\n");printf("\t\t=====2.上传===========\n");printf("\t\t=====0.退出===========\n");printf("请输入选项:");scanf("%d",&menu);getchar();//对菜单多分支选择switch(menu){case 1:{//下载file_download();}break;case 2:{//上传file_upload();}break;case 0:goto END;default:printf("您输入的功能有误,请重新输入\n");}while(getchar()!='\n');system("clear");}END:return 0;
}//创建用于通信的套接字函数
int communication()
{int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd==-1){perror("socket error");return -1;}return sfd;
}//定义上传函数
int file_upload()
{int sfd=communication();system("ls"); //在终端显示当前目录下所有文件printf("请输入你要上传的文件:");char file[128];scanf("%s",file);//以只读的形式打开需要上传的文件的数据int sendfd=-1;if((sendfd=open(file,O_RDONLY))==-1){perror("open file 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);socklen_t socklen=sizeof(sin);//封装请求下载的数据包//第一模块char pack[516]="";short *p1=(short *)pack;*p1=htons(2); //第二模块char *p2=pack+1;strcpy(p2,file);//第三模块int broadcst_permission=1;char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");int len=4+strlen(p2)+strlen(p3);sendto(sfd,pack,len,0,(struct sockaddr*)&sin,sizeof(sin));char *data_point=pack+4;short *menu_point=(short *)pack;*menu_point=htons(3);short *block_point=(short *)(pack+2);*block_point=htons(1);int i=1;while(1){recvfrom(sfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,&socklen);if(*menu_point==htons(4)){int res=read(sendfd,pack+4,512);if(res==0){printf("拷贝完成,按任意按键退出\n");break;}*menu_point=htons(3);sendto(sfd,pack,res+4,0,(struct sockaddr*)&sin,socklen);}}
}
//定义下载函数
int file_download()
{//创建文件描述符用于下载传输过来的数据包int wfd=-1;if((wfd=open("./test.txt",O_WRONLY|O_CREAT|O_TRUNC,0664))==-1){perror("open 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);socklen_t socklen=sizeof(sin);int sfd=-1;if((sfd=communication())==-1){printf("连接失败\n");return -1;}//封装请求下载的数据包//第一模块char pack[516]="";short *p1=(short *)pack;*p1=htons(1);//第二模块printf("请输入你要下载的文件:");char file[128];scanf("%s",file);char *p2=pack+2;strcpy(p2,file);//第三模块char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");int len=4+strlen(p2)+strlen(p3);sendto(sfd,pack,len,0,(struct sockaddr*)&sin,sizeof(sin));while(1){int res=0;if((res=recvfrom(sfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,&socklen))<0){perror("recvfrom error");return -1;}char *data_point=pack+4;short *menu_point=(short*)pack;short *block_point=(short*)(pack+2);if(res<516){write(wfd,data_point,res-4);printf("文件拷贝完成\n");break;}write(wfd,data_point,512);//完成了一次拷贝,要向客户端发送ACK包char ack[4];short *p1=(short *)ack;short *p2=(short *)(ack+2);*p1=htons(4);*p2=*block_point;sendto(sfd,ack,4,0,(struct sockaddr*)&sin,sizeof(sin));}}