9.10网编——项目1机械臂,TFTP手写
1.机械臂
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <termios.h> // 用于终端设置
#include <25061head.h>
#define SER_PORT 8888 // 与服务器保持一致
#define SER_IP "192.168.108.140" // 服务器IP地址
#define CLI_PORT 9999 // 客户端端口号
#define CLI_IP "192.168.144.128" // 客户端IP地址
int main(int argc, const char *argv[])
{
//注释掉的语句是从/dev/input/event1中采集数据实现操作//打开操作的文件
// int fd = open("/dev/input/event1",O_RDONLY);
// if(fd==-1)
// {
// ERR_MSG("open error");
// return -1;
// }//设置成无缓冲,从终端输入立即执行static struct termios old_termios;tcgetattr(STDIN_FILENO, &old_termios);struct termios new_termios = old_termios;// 禁用回显和缓冲new_termios.c_lflag &= ~(ICANON | ECHO);// 设置读取超时new_termios.c_cc[VTIME] = 0;new_termios.c_cc[VMIN] = 1;tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);//创建套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd==-1){ERR_MSG("socket error");return -1;}printf("创建成功\n");//bind设置地址struct sockaddr_in cin;cin.sin_family=AF_INET;cin.sin_port=htons(CLI_PORT);cin.sin_addr.s_addr=inet_addr(CLI_IP);if(-1==bind(cfd,(struct sockaddr*)&cin,sizeof(cin))){ERR_MSG("bind error");return -1;}printf("地址设置成功\n");//connect连接服务器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(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){ERR_MSG("connect error");return -1;}printf("连接成功\n");/* //接收键盘操作的数据struct input_event ie;//初始化机械臂*/char buf1[5]={0xff,0x02,0x00,0x00,0xff};//红机械臂unsigned char buf2[5]={0xff,0x02,0x01,0x5a,0xff};//蓝机械臂send(cfd,buf1,sizeof(buf1),0);sleep(1);send(cfd,buf2,sizeof(buf2),0);//终端输入的容器char num;while(1){//read(fd,&ie,sizeof(ie));//循环输入wsad的指令num=getchar();//switch(ie.code * ie.value)switch(num){case 'w'://wbuf1[3]=buf1[3]+2;if(buf1[3]>90){printf("超过机械臂最大范围\n");buf1[3]=90;}else if(buf1[3]<(-90)){printf("超过机械臂最大范围\n");buf1[3]=-90;}send(cfd,buf1,sizeof(buf1),0);break;case 's'://sbuf1[3]=buf1[3]-2;if(buf1[3]>90){printf("超过机械臂最大范围\n");buf1[3]=90;}else if(buf1[3]<(-90)){printf("超过机械臂最大范围\n");buf1[3]=-90;}send(cfd,buf1,sizeof(buf1),0);break;case 'a'://abuf2[3]=buf2[3]-2;if(buf2[3]>180){printf("超过机械臂最大范围\n");buf2[3]=180;}if(buf2[3]<0){printf("超过机械臂最大范围\n");buf2[3]=0;}send(cfd,buf2,sizeof(buf2),0);break;case 'd'://dbuf2[3]=buf2[3]+2;if(buf2[3]>180){printf("超过机械臂最大范围\n");buf2[3]=180;}if(buf2[3]<0){printf("超过机械臂最大范围\n");buf2[3]=0;}send(cfd,buf2,sizeof(buf2),0);break;}fflush(stdout);}close(cfd);
// close(fd);return 0;
}
2.TFTP
#include <stdio.h>
#include <25061head.h>
#define cli_ip "192.168.144.128"
#define cli_port 8888
#define ser_ip "192.168.108.140"
#define ser_port 69int main(int argc, const char *argv[])
{//socketint cfd=socket(AF_INET,SOCK_DGRAM,0);if(-1==cfd){ERR_MSG("socket error:");return -1;}printf("socket success\n");
//bindstruct sockaddr_in cin;cin.sin_family=AF_INET;cin.sin_port=htons(cli_port);cin.sin_addr.s_addr=inet_addr(cli_ip);if(-1==bind(cfd,(struct sockaddr*)&cin,sizeof(cin))){ERR_MSG("bind error");return -1;}printf("bind success\n");NEXT1:;//循环读写前配置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 addrlen = sizeof(sin);short num=0;//块编号printf("*****************\n");printf("*****1.下载******\n");printf("*****2.上传******\n");printf("*****************\n");printf("请输入编号");int n=0;scanf("%d",&n);char buf[516]="";char filename[21]="";short *p1= (short*)buf;char *p2=buf+2;char *p4;int buflen;int fd;
switch(n)
{
case 1://起始配置*p1=htons(1);printf("请输入下载的文件名:");scanf("%s",filename);getchar();strcpy(p2,filename);p4=p2+strlen(filename)+1;strcpy(p4,"octet");buflen=4+strlen(p2)+strlen(p4);//发送读写请求sendto(cfd,buf,buflen,0,(struct sockaddr*)&sin,addrlen);printf("读写请求发送成功\n");//接收数据包fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC, 0664);while(1){bzero(buf,sizeof(buf));int recv_len=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);//收printf("读取的字节大小%d\n",recv_len);//打印读取过程short errornum=ntohs(*(short*)buf);//errornum是操作码,判断操作码是否等于5,是5则报错,是3则是数据包if(errornum==5){ERR_MSG("recv error");return -1;}else if(errornum==3){short block_num = ntohs(*(short*)(buf + 2)); //写入文件,从第五个字节开始写,前面4字节都是前缀ssize_t size=write(fd,buf+4,recv_len-4);printf("读到512字节消息,还有未读字节\n");*(short*)buf = htons(4); // 操作码设成4的网络字节序,用来发送ASK确认包*(short*)(buf + 2) = htons(block_num); // 确认当前块编号sendto(cfd,buf,4,0,(struct sockaddr*)&sin,addrlen);//发送前四字节,正好是ASK包if(recv_len<516){printf("读取到文件结尾\n");break;}}}printf("文件下载成功\n");close(fd);close(cfd);printf("按任意键返回上一层\n");getchar();
goto NEXT1;
case 2://上传//配置读写请求包*p1=htons(2);printf("请输入上传的文件名:");scanf("%s",filename);strcpy(p2,filename);fd = open(filename, O_RDONLY);p4=p2+strlen(filename)+1;strcpy(p4,"octet");buflen=4+strlen(p2)+strlen(p4);//发送读写请求sendto(cfd,buf,buflen,0,(struct sockaddr*)&sin,addrlen);printf("读写请求发送成功\n");num=0;while(1){bzero(buf,sizeof(buf));//接收ASK申请包int recv_len=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);printf("hello\n");short opcode = ntohs(*p1);if(opcode==5){printf("错误码为:%s",buf+4);break;}num++;//跳过前四个字节,不是正文ssize_t ret = read(fd, buf + 4, 512);//操作码改成3*p1=htons(3);*(short*)(buf+2) = htons(num);//发送sendto(cfd, buf, ret+4, 0, (struct sockaddr*)&sin, addrlen);//打印发送过程printf("发送块%d号发送:(%ld字节)\n", num, ret);// 小于512字节,则读取到文件结尾if (ret==0){printf("读取到文件结尾\n");break;}}printf("文件上传成功\n");close(fd);printf("返回\n");getchar();goto NEXT1;
}close(cfd);return 0;
}