网络编程学习

CP机械臂测试

cpp 复制代码
#include<myhead.h>
#define SER_IP "192.168.125.193"      //服务器ip
#define SER_PORT 8888               //服务器端口号

#define CLI_IP "192.168.152.135"      //客户端IP
#define CLI_PORT 8910               //客户端端口号

int main(int argc, const char *argv[])
{
    //1、创建用于通信的套接字文件描述符
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("cfd = %d\n", cfd);          //3

    //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] += 2;       //每次操作的角度偏移2读
                if(rbuf[3] >= 90)
                {
                    rbuf[3] = 90;
                }
                send(cfd, rbuf, sizeof(rbuf), 0);
            }
            break;

		case'S':
		case's':
			{
				rbuf[3]-=2;
				if(rbuf[3]<=-90)
				{
					rbuf[3]=-90;
				}
				send(cfd,rbuf,sizeof(rbuf),0);
			}
			break;
		case'D':
		case'd':
			{
				bbuf[3]+=2;
				if(bbuf[3]>=180)
				{
					bbuf[3]=180;
				}
				send(cfd,bbuf,sizeof(bbuf),0);
			}
			break;
		case'A':
		case'a':
			{
				bbuf[3]-=2;
				if(bbuf[3]<=0)
				{
					bbuf[3]=0;
				}
				send(cfd,bbuf,sizeof(bbuf),0);
			}
			break;
        }
    }



    //5、关闭套接字
    close(cfd);

    return 0;
}

基于UDP的TFTP文件传输

cpp 复制代码
#include<myhead.h>
#define SER_IP "192.168.125.64"
#define SER_POTR 69
int 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[])
{
	
	system("clear");
	//创建通信套接字
	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)
	{
		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;
		}
	}

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);//存入文件名及结尾的0
	char *p3=p2+strlen(p2)+1;
	strcpy(p3,"octet");//存入模式位及结尾的0
	int 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;
	}
	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<sizeof(pack))
		{
			//最后一次回复ACK
			sendto(cfd,pack,4,0,(struct sockaddr*)&sin,sizeof(sin));
			printf("下载完成!\n");
			break;//结束循环
		}
		//返回ACK包
		if(sendto(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,sizeof(sin))==-1)
		{
			perror("download ACK sendto error");
			return -1;
		}	
	}
	return 0;
}
int my_upload(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(2);//存入前两字节的操作码2代表写(上传)
	char *p2=pack+2;
	strcpy(p2,txt);//存入文件名及结尾的0
	char *p3=p2+strlen(p2)+1;
	strcpy(p3,"octet");//存入模式位及结尾的0
	int packlen=4+strlen(p2)+strlen(p3);
	if(sendto(cfd,pack,packlen,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("upload request sendto error");
		return -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_upload recvfrom error");
		return -1;
	}
	int ack=recv_ack(pack,res);
	if(ack==-1)
	{
		puts("recv_ack error");
		return -1;
	}
	//2.开始上传数据
	//2.1只读形式打开要上传的文件
	int rfd=open(txt,O_RDONLY);
	if(rfd==-1)
	{
		perror("upload open error");
		return -1;
	}
	int i=1;
	while(1)
	{
		bzero(pack,sizeof(pack));
		//2.2设置发送数据的协议包
		*p1=htons(3);//前两字节操作码为3时代表此为数据包
		*(p1+1)=htons(i);//设置块编码从1开始
		int rres=read(rfd,pack+4,512);//从文件中读取512数据存入数据域
		packlen=4+rres;//本次的数据包大小
		//发送数据
		if(sendto(cfd,pack,packlen,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
		{
			perror("upload data sandto error");
			return -1;
		}
		if((res=(recvfrom(cfd,pack,sizeof(pack),0,(struct sockaddr*)&sin,&sinlen)))==-1)
		{
			perror("my_upload recvfrom error");
			return -1;
		}
		ack=recv_ack(pack,res);//读取服务器的回复消息
		if(ack==-1)
		{
			puts("recv_ack error");
			return -1;
		}else if(ack<i)//服务器返回的块编码小于当前发送的
		{
			//光标返回发送之前的位置重新发送
			lseek(rfd,-res,SEEK_CUR);
		}else if(ack==i)//服务器已接收该数据包可以发送下一个
		{
			i++;//块编码+1
		}
		if(rres<512)//发送完成
		{
			printf("上传完成!\n");
			break;
		}
	}
	close(rfd);
	return 0;
}
int my_save_data(char *p,int len)
{
	//追加写的形式创建一个文件存储下载的数据
	int wfd=open("./downtxt",O_WRONLY|O_APPEND|O_CREAT,0664);
	if(wfd==-1)
	{
		perror("my_download open error");
		return -1;
	}
	write(wfd,p,len);
	close(wfd);
	return 0;
}
int recv_ack(char *pack,int res)
{
	short *p=(short*)pack;
	short num=ntohs(*p);//获取发来消息的操作码
	switch(num)
	{
	case 3:
		{
			//保存数据
			int seve=my_save_data(pack+4,res-4);
			if(seve==-1)
			{
				puts("my_save_data error");
				return -1;
			}
		}break;
	case 4:
		break;
	case 5:
		{
			//收到错误码 输出差错码和差错信息
			printf("ERROR:%d:%s\n",ntohs(*(p+1)),pack+4);
			return -1;
		}break;
	}
	return ntohs(*(p+1));//返回块编码
}
相关推荐
BingoGo5 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack5 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
DianSan_ERP4 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习