网络编程学习

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));//返回块编码
}
相关推荐
oneouto6 分钟前
selenium学习笔记(二)
笔记·学习·selenium
ProcessOn官方账号7 分钟前
如何绘制网络拓扑图?附详细分类解说和用户案例!
网络·职场和发展·流程图·拓扑学
sealaugh3211 分钟前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
Ven%31 分钟前
如何在防火墙上指定ip访问服务器上任何端口呢
linux·服务器·网络·深度学习·tcp/ip
炭烤玛卡巴卡37 分钟前
学习postman工具使用
学习·测试工具·postman
thesky1234561 小时前
活着就好20241224
学习·算法
神的孩子都在歌唱1 小时前
TCP/IP 模型中,网络层对 IP 地址的分配与路由选择
网络·tcp/ip·智能路由器
阿雄不会写代码1 小时前
ubuntu安装nginx
linux·服务器·网络
蜗牛hb1 小时前
VMware Workstation虚拟机网络模式
开发语言·学习·php
汤姆和杰瑞在瑞士吃糯米粑粑1 小时前
【C++学习篇】AVL树
开发语言·c++·学习