【嵌入式学习】网络编程day03.02

文章详细描述了使用TCP和UDP协议进行的机械臂控制,以及基于UDP的TFTP协议实现的文件传输,展示了如何通过编程接口进行网络通信和文件操作。
摘要由CSDN通过智能技术生成

一、项目

1、TCP机械臂测试

#include <myhead.h>
#define SER_IP "192.168.126.32"
#define SER_PORT 8888
#define CER_IP "192.168.126.42"
#define CER_PORT 9891
int main(int argc, const char *argv[])
{
	int wfd=-1;
	//创建套接字
	if((wfd=socket(AF_INET,SOCK_STREAM,0))==-1)
	{
		perror("error");
		return -1;
	}
	/*
	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(CER_PORT);
	cin.sin_addr.s_addr=inet_addr(CER_IP);

	if(bind(wfd,(struct sockaddr *)&cin,sizeof(cin))==-1)
	{
		perror("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(wfd,(struct sockaddr *)&sin,sizeof(sin))==-1)
	{
		perror("error3");
		return -1;
	}

	char red[5]={0xff,0x02,0x00,0x00,0xff};
	unsigned char blue[5]={0xff,0x02,0x01,0x00,0xff};
	send(wfd,red,sizeof(red),0);
	sleep(1);
	send(wfd,blue,sizeof(blue),0);
	char c=0;
	while(1)
	{
		//写入操作
		system("stty -icanon");
		c=getchar();
		switch(c)
		{
		case 'w':
			{
				red[3]-=5;
				if(red[3]<=-90)
				{
					red[3]=-90;
				}
				send(wfd,red,sizeof(red),0);
				break;
			}
		case 's':
			{
				red[3]+=5;
				if(red[3]>=90)
				{
					red[3]=90;
				}
				send(wfd,red,sizeof(red),0);
				break;
			}
		case 'a':
			{
				blue[3]-=5;
				if(blue[3]>=180)
				{
					blue[3]=0;
				}
				send(wfd,blue,sizeof(blue),0);	
				break;
			}
		case 'd':
			{
				blue[3]+=5;
				if(blue[3]>=180)
				{
					blue[3]=180;
				}
				send(wfd,blue,sizeof(blue),0);	
				break;
			}
fault:{
		  printf("error\n");
		  break;
	  }
		}
	}
		close(wfd);
		return 0;
	}

 

2、基于UDP的TFTP的文件传输

#include <myhead.h>
#define SER_IP "192.168.126.32"
#define SER_PORT 69
int Recv(char *name,int cfd,struct sockaddr_in sin)
{
	//下载请求
	char pack[516]={0};
	short *p1 =(short *)pack;
	*p1 = htons(1);          //设置操作码
	strcpy(pack+2, name);         //文件名
	strcpy(pack+2+strlen(name)+1, "octet");            //模式位
	int packlen = 2+strlen(name)+1 + strlen("octet")+1;    //请求包的大小

	//向服务器发送请求
	sendto(cfd,pack,packlen,0,(struct sockaddr *)&sin,sizeof(sin));

	//打开一个只写文件
	int wrt_fd=-1;
	if((wrt_fd=open(name,O_WRONLY|O_CREAT,0664))==-1)
	{
		perror("wrt_fd error");
		return -1;
	}
	char wbuf[516]="";
	socklen_t socklen=sizeof(sin);
	while(1)
	{
		int recvkeys=recvfrom(cfd,wbuf,sizeof(wbuf),0,(struct sockaddr *)&sin,&socklen);
		if(recvkeys==-1)
		{
			perror("recv reeor");
			close(wrt_fd);
			return -1;
		}
		//printf("接收服务器数据包\n");
		short pw=ntohs(*(short *)wbuf);
		short pw1=ntohs(*(short *)(wbuf+2));
		//		printf("错误码%d\n",pw1);
		//		printf("%d\n",pw);
		//		
		if(pw==3)
		{
			//printf("正在下载数据\n");
			//printf("size%d\n",recvkeys);
			if(recvkeys==516)
			{
				//printf("正在接收数据\n");
				write(wrt_fd,wbuf+4,recvkeys-4);
				char ACK[4];
				*(short *)ACK=htons(4);
				*(short *)(ACK+2)=htons(pw1);
				sendto(cfd,ACK,4,0,(struct sockaddr *)&sin,sizeof(sin));
			}
			else if(recvkeys<516)
			{
				write(wrt_fd,wbuf+4,recvkeys-4);
				char ACK[4];
				*(short *)ACK=htons(4);
				*(short *)(ACK+2)=htons(pw1);	
				sendto(cfd,ACK,4,0,(struct sockaddr *)&sin,sizeof(sin));
				printf("下载完毕\n");
				break;
			}
		}	
		else if(pw==5)
		{
			printf("ERRROR:%d",pw1);
		}
	}
	close(wrt_fd);
}
int Send(char *name,int cfd,struct sockaddr_in sin)
{
	char pack[516];
	short *p1 =(short *)pack;
	*p1 = htons(2);          //设置操作码
	strcpy(pack+2, name);         //文件名
	strcpy(pack+2+strlen(name)+1, "octet");            //模式位
	int packlen = 2+strlen(name)+1 + strlen("octet")+1;    //请求包的大小

	//向服务器发送请求
	sendto(cfd,pack,packlen,0,(struct sockaddr *)&sin,sizeof(sin));

	//打开一个只读文件
	int rd_fd=-1;
	if((rd_fd=open(name,O_RDONLY))==-1)
	{
		perror("rd_fd error");
		return -1;
	}
	char rbuf[512]="";
	socklen_t socklen=sizeof(sin);
	//接收服务器发送的应答包,确认是否可以发送数据
	int keys=recvfrom(cfd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&sin,&socklen);
	//提取ACK的操作码
	short pr=ntohs(*(short *)rbuf);
	//提取ACK的块编号
	short pr1=ntohs(*(short *)(rbuf+2));
	//设置发送数据包的块编号
	short n=1;
	//判断操作码是否为4
	if(pr==4)
	{
		while(1)
		{
			//清空数组
			bzero(rbuf,sizeof(rbuf));
			int num=read(rd_fd,rbuf,sizeof(rbuf));
			if(num==0)
			{
				printf("上传完毕\n");
				break;
			}
			//整合读取数据为数据包并且发送至服务器

			char data[516];
			short *p1 =(short *)data;
			*p1 = htons(3);          //加入操作码
			*(p1+1)=htons(n);
			memcpy(data+4,rbuf,num);		//将读取数据整合
			//向服务器发送数据
			sendto(cfd,data,sizeof(data),0,(struct sockaddr *)&sin,sizeof(sin));
			//等待服务器返回应达包
			char ACK[4];
			int recvkeys=recvfrom(cfd,ACK,sizeof(ACK),0,(struct sockaddr *)&sin,&socklen);
			n=ntohs(*(short *)(ACK+2))+1;
			//printf("%d\n",n);
			int oc=ntohs(*(short *)(ACK));
			//printf("%d\n",oc);
			if(recvkeys==-1)
			{
				perror("recv reeor");
				close(rd_fd);
				return -1;
			}
			if(oc==5)
			{
				printf("error:%d",oc);
				return -1;
			}

			else if(pr==5)
			{
				printf("ERROR:%d\n",pr1);
			}
		}
		close(rd_fd);
	}
}
int main(int argc, const char *argv[])
{
	int wfd=-1;
	//创建套接字
	if((wfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
	{
		perror("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);	
while(1)
{
	sleep(1);
	system("clear");
	//设置选择界面
	printf("\t\t***********1、下载**************\t\n");
	printf("\t\t***********2、上传**************\t\n");
	printf("\t\t***********3、退出**************\t\n");
	int key;
	printf("请选择:");
	scanf("%d",&key);
	switch(key)
	{
	case 1:
		{
			char name[128]="";
			printf("输入下载的文件:");
			scanf("%s",name);
			Recv(name,wfd,sin);
		
		}
			break;
	case 2:
		{
			char name[128]="";
			printf("输入上传的文件:");
			scanf("%s",name);
			Send(name,wfd,sin);
	
		}
			break;
	case 3:
		{
			printf("已退出程序\n");
			return 0;
		
		}
			break;
	default :
			{
				printf("错误输入\n");
				break;
			}
	}
}

	close(wfd);
	return 0;
}

现象 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值