网络编程学习

1.编写机械臂简易客户端

cpp 复制代码
#include<myhead.h>

#define SER_IP "192.168.108.153"
#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);
	socklen_t addrlen=sizeof(sin);

	//连接服务器
	if(connect(sfd,(struct sockaddr*)&sin,addrlen)==-1)
	{
		perror("connect error");
		return -1;
	}

	//初始化机械臂
	char rbuf[5]={0xff,0x02,0x00,0xa6,0xff};
	unsigned char bbuf[5]={0xff,0x02,0x01,0xb4,0xff};

	send(sfd,rbuf,sizeof(rbuf),0);
	send(sfd,bbuf,sizeof(bbuf),0);

	printf("按w红色手臂角度增大\n");
	printf("按s红色手臂角度增大\n");
	printf("按d蓝色手臂角度增大\n");
	printf("按a蓝色手臂角度增大\n");
	printf("按q退出\n");

	//操控机械臂
	char c;
	while(1)
	{
		c=getchar();
		switch(c)
		{
		case 'w':
			{
				if(rbuf[3]>=0x5a)
					break;
				rbuf[3]+=2;
				send(sfd,rbuf,sizeof(rbuf),0);
				break;
			}
		case 's':
			{
				if(rbuf[3]>=0xa6)
					break;
				rbuf[3]-=2;
				send(sfd,rbuf,sizeof(rbuf),0);
				break;
			}
		case 'd':
			{
				if(bbuf[3]>=0xb4)
					break;
				bbuf[3]+=2;
				send(sfd,bbuf,sizeof(bbuf),0);
				break;
			}
		case 'a':
			{
				if(bbuf[3]<=0x02&&bbuf[3]!=0x00)
					bbuf[3]=0x00;
				else if(bbuf[3]==0x00)
					break;
				bbuf[3]-=2;
				send(sfd,bbuf,sizeof(bbuf),0);
				break;
			}
		case 'q':
			{
				rbuf[3]=0xa6;
				bbuf[3]=0xb4;
				send(sfd,rbuf,sizeof(rbuf),0);
				send(sfd,bbuf,sizeof(bbuf),0);
				close(sfd);
				return 0;
			}
		default :
			break;
		}
	}
	return 0;
}

2、基于UDP完成tftp客户端实现

cpp 复制代码
#include<myhead.h>

#define SER_PORT 69

//定义下载文件函数
int my_copy(int sfd,struct sockaddr_in sin,socklen_t addrlen)
{
	char buf[516]="";
	char filename[20]="";
	printf("请输入你要下载的文件名:\n");
	getchar();
	fgets(filename,sizeof(filename),stdin);
	filename[strlen(filename)-1]=0;

	//用只写的形式打开一个文件
	int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
	if(fd==-1)
	{
		perror("open error");
		return -1;
	}

	//确认是下载文件,还是传输文件
	short *p1=(short *)buf;
	*p1=htons(1);

	//要下载或者传输的数据名
	char *p2=buf+2;
	strcpy(p2,filename);

	//填入模式
	char *p4=p2+strlen(filename)+1;
	strcpy(p4,"octet");

	//定义传输大小
	int size=2+strlen(p2)+strlen(p4)+2;

	//传输请求
	sendto(sfd,buf,size,0,(struct sockaddr*)&sin,addrlen);

	//数据收发
	while(1)
	{
		int res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		if(res==-1)
		{
			perror("recvfrom error");
			close(sfd);
			close(fd);
			return -1;
		}
		char *p=buf+4;

		p1=(short *)buf;
		//如果发过来的是错误信息
		if(ntohs(*p1)==5)
		{
			printf("%s\n",p);
			close(sfd);
			close(fd);
			return -1;
		}
		int num=res-4;  //文件中可能有\0,所以不能用strlen求读取的大小

		//写入数据
		if(num<512)
		{
			write(fd,p,num);
			break;
		}
		write(fd,p,num);
		*p1=htons(4);

		//发送ack
		sendto(sfd,buf,4,0,(struct sockaddr*)&sin,addrlen);
	}
	close(fd);
	printf("下载成功\n");
	return 0;
}

//定义文件传输函数
int my_trans(int sfd,struct sockaddr_in sin,socklen_t addrlen)
{
	char buf[516]="";
	char filename[20]="";
	printf("请输入你要传输的文件名:\n");
	getchar();
	fgets(filename,sizeof(filename),stdin);
	filename[strlen(filename)-1]=0;

	//用只写的形式打开一个文件
	int fd=open(filename,O_RDONLY);
	if(fd==-1)
	{
		perror("open error");
		return -1;
	}

	//确认是下载文件,还是传输文件
	short *p1=(short *)buf;
	*p1=htons(2);

	//要下载或者传输的数据名
	char *p2=buf+2;
	strcpy(p2,filename);

	//填入模式
	char *p4=p2+strlen(filename)+1;
	strcpy(p4,"octet");

	//定义传输大小
	int size=2+strlen(p2)+strlen(p4)+2;

	//传输请求
	sendto(sfd,buf,size,0,(struct sockaddr*)&sin,addrlen);

	int count=1;
	char rbuf[512]="";

	int res1=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
	if(res1==-1)
	{
		perror("rescvfrom error");
		close(sfd);
		close(fd);
		return -1;
	}

	p1=(short *)buf;

	//如果接收的是错误信息
	if(ntohs(*p1)==5)
	{
		printf("%s\n",buf+4);
		close(sfd);
		close(fd);
		return -1;
	}

	char *k2=(char *)buf+2;
	if(ntohs(*k2)!=0)
	{
		close(sfd);
		close(fd);
		return -1;
	}
	//数据收发
	while(1)
	{
		bzero(rbuf,0);
		int res=read(fd,rbuf,sizeof(rbuf));
		if(res==0)
			break;
		else if(res==-1)
		{
			perror("read error");
			close(fd);
			return -1;
		}
		*p1=htons(3);     //发送包的操作码
		short *k=(short *)(buf+2);
		*k=htons(count);
		char *p=buf+4;
		memcpy(p,rbuf,res);
		int size1=2+2+res;


		//发送数据包
		sendto(sfd,buf,size1,0,(struct sockaddr*)&sin,addrlen);


		//接受ack包
		if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen)==-1)
		{
			perror("rescvfrom error");
			close(fd);
		}

		//p1=(short *)buf;

		//如果接收的是错误信息
		if(ntohs(*p1)==5)
		{
			printf("%s\n",p);
			close(fd);
			return -1;
		}
		k=(short *)(buf+2);
		if(ntohs(*k)!=count)
		{
			close(fd);
			return -1;
		}
		//count自增
		count++;
	}
	close(fd);
	printf("下载成功\n");
	return 0;
}


int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("请先输入IP地址:\n");
		return -1;
	}

	int sfd=socket(AF_INET,SOCK_DGRAM,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(argv[1]);
	socklen_t addrlen=sizeof(sin);

	while(1)
	{
		printf("1>>>>>>>>>下载文件\n");
		printf("2>>>>>>>>>传输文件\n");
		printf("3>>>>>>>>>退出系统\n");

		int choose;
		printf("请输入操作:\n");
		scanf("%d",&choose);
		switch(choose)
		{
		case 1:
			{
				if(my_copy(sfd,sin,addrlen)==-1)
					return -1;
				break;
			}
		case 2:
			{
				if(my_trans(sfd,sin,addrlen)==-1)
					return -1;
				break;
			}
		case 3:
			{
				close(sfd);
				return 0;
			}
		default :
			{
				printf("无效的操作,请重新输入操作\n");
				break;
			}
		}
	}

	return 0;
}
相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
DianSan_ERP6 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习