网络编程 总结二

news2024/12/22 23:37:49

一、TCP

TCP模型

1. TCP搭建相关函数:

 套接字Socket

 1)Socket函数:

2)bind

 3)listen

 4)accept

 5)recv

 注意:

1> TCP中的recv 可以替换成read;         2>TCP中的recv可以替换成recvfrom

6)send

  注意:

1> TCP中的send 可以替换成 write;         2>TCP中的 send 可以替换成 sendto

7)connet

 客户端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"liine %d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.8.77"  //本机IP 
#define PORT 6666          // 1024-49151

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("cfd=%d\n",cfd);
	//允许端口快速重用
	int reuse=1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	//填充地址信息结构体
	//真是的地址信息结构体根据地址族制定  AF_INET: man 7 ip
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//必须填 AF_INET
	sin.sin_port = htons(PORT);//端口号, 1024-49151
	sin.sin_addr.s_addr = inet_addr(IP);//本机IP,ifconfig
	
	//连接服务器
	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("connet");
		return -1;
	}
	printf("connect  sucess __%d__\n",__LINE__);

	char buf[128]="";
	ssize_t res=0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		printf("请输入数据>>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]=0;

		//发送
		if(send(cfd,buf,sizeof(buf),0)<0)
		{
			ERR_MSG("send");
			return -1;
		}
		printf("send sucess\n");

		//接收
		bzero(buf,sizeof(buf));
		
		res=recv(cfd,buf,sizeof(buf),0);
		if(res<0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0==res)
		{
			printf("cfd=%d 服务器下线 __%d__\n",	cfd,__LINE__);
			break;
		}
		printf("cfd=%d %s __%d__\n",cfd,buf,__LINE__);

	}

	close(cfd);
	return 0;
}

服务器:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"liine %d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.8.77"  //本机IP 
#define PORT 6666          // 1024-49151

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("sfd=%d\n",sfd);
	//允许端口快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	//填充地址信息结构体
	//真是的地址信息结构体根据地址族制定  AF_INET: man 7 ip
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//必须填 AF_INET
	sin.sin_port = htons(PORT);//端口号, 1024-49151
	sin.sin_addr.s_addr = inet_addr(IP);//本机IP,ifconfig

	//将IP和端口号绑定到套接字上
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind sucess __%d__\n",__LINE__);

	//将套接字设置为被动监听状态,监听是否有客户端连接成功
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);

	struct sockaddr_in cin;        // 存储连接成功的客户端地址信息  
	socklen_t addrlen = sizeof(cin);

	//阻塞函数,从已完成连接的队列头中获取一个客户端信息
	//该文件描述符才是与客户端通信的文件描述符
	int newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
	if(newfd<0)
	{
		ERR_MSG("accept");
		return -1;
	}
	printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

	char buf[128]="";
	ssize_t res=0;
	while(1)
	{
		//接收
	
		res=recv(newfd,buf,sizeof(buf),0);
		if(res<0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0==res)
		{
			printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
			break;
		}
		printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

		//发送
		strcat(buf,"*_*");
		if(send(newfd,buf,sizeof(buf),0)<0)
		{
			ERR_MSG("send");
			return -1;
		}
		printf("send sucess\n");
	}

	close(newfd);
	close(sfd);
	return 0;
}

二、UDP

UDP模型

 1. UDP相关函数

1)socket

2)bind

3)recvfrom

 4)sendto

 客户端:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"line:%d",__LINE__);\
	perror(msg);\
}while(0)

#define SER_IP "192.168.8.77" //本机IP 
#define SER_PORT 6666

#define CLI_IP "192.168.8.77" //本机IP 
#define CLI_PORT 8888

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int cfd = socket(AF_INET, SOCK_DGRAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
//*****************************************************	
	struct sockaddr_in cin;
	cin.sin_family  = AF_INET;      //必须填AF_INET
	cin.sin_port = htons(CLI_PORT);     //端口号的网络字节符
	cin.sin_addr.s_addr = inet_addr(CLI_IP);
	
	if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("client bind success\n");
//********************************************************
	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family  = AF_INET;      //必须填AF_INET
	sin.sin_port = htons(SER_PORT);     //端口号的网络字节符
	sin.sin_addr.s_addr = inet_addr(SER_IP);

	struct sockaddr_in rcvaddr;//存储数据包是从哪里来的
	socklen_t addrlen = sizeof(rcvaddr);

	char buf[128]="";
	ssize_t res =0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		printf("请输入数据>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]=0;

		//发送数据,发送给服务器
		if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf("发送数据\n");

		//接收数据,必须接收数据包的发送方地址信息
		res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rcvaddr,&addrlen);
		if(res<0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[%s : %d]: %s\n",inet_ntoa(rcvaddr.sin_addr), ntohs(rcvaddr.sin_port),buf);
	}
	//关闭文件描述符
	close(cfd);
	
	return 0;
}

服务器:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"line%d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.8.77" //本机IP 
#define PORT 6666

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd = socket(AF_INET, SOCK_DGRAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}

	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family  = AF_INET;      //必须填AF_INET
	sin.sin_port = htons(PORT);     //端口号的网络字节符
	sin.sin_addr.s_addr = inet_addr(IP);

	//绑定 必须绑定
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}

	struct sockaddr_in cin;//存储数据包是从哪里来的
	socklen_t addrlen = sizeof(cin);

	char buf[128]="";
	ssize_t res =0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		//接收数据,必须接收数据包的发送方地址信息
		res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen);
		if(res<0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[%s : %d]: %s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),buf);
		
		strcat(buf,"*_*");
		if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin))<0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf("发送成功\n");
	}
	//关闭文件描述符
	close(sfd);
	
	return 0;
}

2.UDP中的connect 函数(重点

1>TCP中的connect函数会造成三次握手,将client 与 server 连接;UDP中的connect 仅仅是将对端的 IP 和端口号记录到内核中。此时UDP只能与记录的对端进行通信。

2>TCP中的connect 函数只能调用一次;UDP中的可以调用多次 connect 函数,刷新内核中对端的IP地址和端口,如果想要清空内核中对端的地址信息,则可以将sin_family 成员修改成AF_UNSPEC

3>当UDP采用connect 方式收发报文后,可以调用 send write 函数 也可以调用sendto函数。

1> sendto ( sd,buf,sizeof ( buf ) , NULL , 0 );

recvfrom 在后面的地址信息结构体填NULL 的时候,可以替换成 recv  read

2> recvfrom ( sockfd , buf, len , flags , NULL ,NULL );

 UDP调用connect 函数的优点:

1>提升传输效率:

a.  不调用connect :将对端的地址信息填充到内核--> 发送报文--->清空内核信息--->将对端的地址信息填充到内核-->发送报文--->清空内核信息

b.  调用了connect :将对端的地址信息填充到内核--> 发送报文--> 发送报文--> 发送报文--->清空内核信息

2>增加传输的稳定性:

a. 调用connect 函数的UDP通信,可以防止AB进程在数据传输过程中收到C进程消息,造成传输错误

3. UDP多点通信

【1】网络属性

setsockopt / getsockopt

 

 【2】多点通信

1. 单播

1>主机之间一对一的通信模式,交换机以及路由器对数据只进行转发,不复制

2>每次只有两个实体相互通信,发送端和接收端都是唯一确定的

2. 广播

1>主机之间一对多的通信模式,网络对其中的每一台主机发出的信号都进行无条件复制并转发

2>在同一个局域网下的所有主机都可以接收到广播信息

3>禁止广播数据穿过路由器,防止广播数据影响大面积主机

4>广播数据不需要应答,只有UDP才能做广播

5>广播地址:有效网络号+ 全是1 的主机号

1)广播的发送端(类似客户端)

1> socket    创建报式套接字    ;  bind  非必须绑定

2>setsockopt 设置允许广播:level: SOL_SOCKET   optname: SO_BROADCAST

3> 指定接收端的地址信息结构体

                a. IP :  填写广播IP

                b. PORT : 与接收端填充的一致即可

4> sendto    发送广播数据

2)广播的接收端(类似服务器)

1> socket    创建报式套接字    ;  bind  必须绑定

2>填充接收端自身的地址信息结构体

  a. IP :  填写广播IP :有效网络号 + 全是 1 的主机号

                调用bind 函数后,会将本机所有可用IP 地址都绑定到套接字上

                b. PORT : 与发送端填充的一致即可

3> recvfrom    接收广播数据

3. 组播(多播组)

1)组播的发送端(类似客户端)

1>socket    创建报式套接字    ;  bind 非必须绑定

2> 指定接收端的地址信息结构体

  a. IP :  填写组播IP  (224.0.0.0~239.255.255.255,与接收方填充一致)

                b. PORT : 与接收端填充的一致即可

3> sendto    发送组播数据

2)组播的接收端(类似服务器)

1> socket    创建报式套接字    ;  bind  必须绑定

2>setsockopt 加入多播组:level :  IPPROTO_IP     OPTNAME : IP_ADD_MEMBERSHIP   

3>填充接收端自身的地址信息结构体

          a. IP :  填写组播IP 

                b. PORT : 与发送端填充的一致即可

4> recvfrom    接收组播数据

多播snd:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"line:%d",__LINE__);\
	perror(msg);\
}while(0)

#define GRP_IP "243.1.2.3" //本机IP 
#define PORT 6666

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int cfd = socket(AF_INET, SOCK_DGRAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}

	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family  = AF_INET;      //必须填AF_INET
	sin.sin_port = htons(PORT);     //端口号的网络字节符
	sin.sin_addr.s_addr = inet_addr(GRP_IP);

	char buf[128]="";
	ssize_t res =0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		printf("请输入数据>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]=0;

		//发送数据,发送给服务器
		if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf("发送数据\n");
	}
	//关闭文件描述符
	close(cfd);
	return 0;
}

多播rcv:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"line%d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.0.79" //本机IP 
#define GRP_IP "224.1.2.3" //组播IP 
#define PORT 6666

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd = socket(AF_INET, SOCK_DGRAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	//加入多播组
	struct ip_mreqn mq;
	mq.imr_multiaddr.s_addr = inet_addr(GRP_IP);//组播IP
	mq.imr_address.s_addr = inet_addr(IP);
	mq.imr_ifindex=2;
	
	if(setsockopt(sfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0)
	{
		perror("setsockopt");
		return -1;
	}

	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family  = AF_INET;      //必须填AF_INET
	sin.sin_port = htons(PORT);     //端口号的网络字节符
	sin.sin_addr.s_addr = inet_addr(GRP_IP);

	//绑定 必须绑定
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	struct sockaddr_in cin;//存储数据包是从哪里来的
	socklen_t addrlen = sizeof(cin);

	char buf[128]="";
	ssize_t res =0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		//接收数据,必须接收数据包的发送方地址信息
		res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen);
		if(res<0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[%s : %d]: %s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),buf);
	}
	//关闭文件描述符
	close(sfd);
	return 0;
}

三、TFTP协议

1)TFTP协议概述:简单文件传输协议适用于在网络上进行文件传输的一套标准协议,使用UDP传输

特点:应用层协议;基于UDP协议实现

数据传输模式:

                     octet: 二进制模式(常用)

                     mail : 已经不在支持

2)TFTP下载模型

 3)TFTP通信过程总结

1>服务器在69号端口等待客户端的请求

2>服务器若批准请求,则使用临时端口与客户端进行通信

3>每隔数据包的编号都有变化(从1开始)

4>每隔数据包都要得到ACK的确认,如果出现超时,则需要重新发送最后的数据包或ACK包

5>数据长度以512Byte传输,小于512Byte的数据意味着数据传输结束

 4)TFTP协议分析

 代码:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"line:%d",__LINE__);\
	perror(msg);\
}while(0)

#define SER_IP "192.168.171.1" //本机IP 
#define SER_PORT 69

int do_download(int cfd, struct sockaddr_in sin)
{
	//下载请求
	char filename[20]="";
	char buf[516]={0};
	printf("请输入要下载的文件名>>");
	scanf("%s",filename);
	while(getchar()!=10);

	short*p1 = (short*)buf;
	*p1 = htons(1);
	char*p2 = buf+2;
	strcpy(p2,filename);

	char*p3 = p2+strlen(p2);
	char*p4 = p3+1;
	strcpy(p4,"octet");

	int size=strlen(p2)+strlen(p4)+4;

	//发送下载请求协议
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("sendto");
		return -1;
	}
	printf("发送成功\n");

	int fd=-1;
	socklen_t  addrlen=sizeof(sin);
	ssize_t res =0;
	unsigned short num=0;
	int ret=0;	
	while(1)
	{
		bzero(buf,sizeof(buf));
		//接收数据,必须接收数据包的发送方地址信息
		res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		if(res<0)
		{
			ERR_MSG("recvfrom");
			ret=-1;
			break;
		}
		
		if(buf[1]==3)
		{
			if(htons(num+1)==*(unsigned short*)(buf+2))
			{
				//组数据包给服务器
				num++;
				if(1==ntohs(*(unsigned short*)(buf+2)))
				{
					fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
					if(fd<0)
					{
						ERR_MSG("open");
						return -1;
					}
				}
				if(write(fd,buf+4,res-4)<0)
				{
					ERR_MSG("write");
					ret=-1;
					break;
				}
				//回复ACK,由于ACK包和数据包前四个字节只有操作码不一致
				//直接修改数据包的操作码
				buf[1]=4;
				if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))<0)
				{
					ERR_MSG("sendto");
					ret =-1;
					break;
				}
				if(res-4<512)
				{
					printf("文件:%s 上传完毕\n",filename);
					break;
				}
			}
		}
		else if(buf[1]==5)//错误包
		{
			fprintf(stderr,"DOWNLOAD_EROR: %d: %s\n",
					ntohs(*(unsigned short*)(buf+2)),buf+4);
			break;
		}
	}
	close(fd);
	return ret;
}

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int cfd = socket(AF_INET, SOCK_DGRAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}

	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family  = AF_INET;      //必须填AF_INET
	sin.sin_port = htons(SER_PORT);     //端口号的网络字节符
	sin.sin_addr.s_addr = inet_addr(SER_IP);

	char c=0;
	while(1)
	{
		system("clear");
		printf("*****************\n");
		printf("******1.下载*****\n");
		printf("******2.上传*****\n");
		printf("******3.退出*****\n");
		printf("*****************\n");
		c=getchar();
		while(getchar()!=10);
		
		switch(c)
		{
		case'1':
			do_download(cfd,sin);
			break;
		case'2':
			break;
		case'3':
			goto END;
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
		printf("请输入任意字符清屏>>>");
		while(getchar()!=10);
	}

END:
	close(cfd);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/482122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot自定义注解

SpringBoot自定义注解 1. 创建一个注解的基本元素 修饰符&#xff1a;访问修饰符必须为public,不写默认为pubic&#xff1b; 关键字&#xff1a;关键字为interface&#xff1b; 注解名称&#xff1a;注解名称为自定义注解的名称 注解类型元素&#xff1a;注解类型元素是注解中…

Python---闭包,装饰器,设计模式之工厂模式

1. 闭包定义 定义双层嵌套函数&#xff0c; 内层函数可以访问外层函数的变量 将内存函数作为外层函数的返回&#xff0c;此内层函数就是闭包函数 2. 闭包的好处和缺点 优点&#xff1a;不定义全局变量&#xff0c;也可以让函数持续访问和修改一个外部变量 优点&#xff1a…

【数据分析之道-Matplotlib(一)】Matplotlib Pyplot

系列文章目录 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f4c1;评论&#x1f4d2;关注…

Jetson nano之ROS入门- -ROS集成开发搭建与ROS通信学习笔记

文章目录 一、ROS集成开发环境搭建二、ROS通信机制和命令1. 话题通信2. 服务通信3. 参数服务4. ROS常用命令 三、Python实现ROS通信- - 控制和读取小乌龟状态1. 配置package.xml文件2. 配置CMakeLists.txt文件3. 编写Python代码4. 配置launch文件 总结 一、ROS集成开发环境搭建…

反射、枚举

反射的定义&#xff1a;Java的反射机制是在运行状态中&#xff0c;都能对任意的类拿到这个类的所有属性&#xff0c;从而对其进行相应的修改&#xff1b;用途&#xff1a;在日常第三方应用开发中&#xff0c;可以通过反射机制来获取某个类的私有成员变量或是方法&#xff1b;主…

研究生,但是一直摆烂——想办法解决

原因剖析 孤独因为没有朋友&#xff0c; 之前自己思维误区&#xff0c;总觉得好好学习好好锻炼变得优秀就会有朋友&#xff0c;其实不是这个样子的&#xff0c;即使自己一直内卷&#xff0c;但还是很孤独。 现在重新反思自己。 没有朋友因为&#xff1a; 1 外貌 2 聊天的情商…

Which programming language do you choose

NO.1&#xff1a;JavaScript JavaScript&#xff0c;简称JS语言&#xff0c;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的高级编程语言。虽然它是作为开发Web页面的脚本语言而出名的&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript 基…

老王的自动驾驶决策和规划第一章

文章目录 自动驾驶决策规划算法序章第一章&#xff08;1&#xff09; 细说五次多项式&#xff08;2&#xff09; 凸优化与非凸优化(3) 直角坐标与自然坐标转换(上, 下) 自动驾驶决策规划算法 序章 课程链接&#xff1a;序章 第一章 &#xff08;1&#xff09; 细说五次多项…

关于SpringBoot整合Websocket实现简易对话聊天窗

前言 官网链接&#xff1a;Websocket Websocket 是什么&#xff1f;它可以将两个独立的浏览器窗口作为通信的两端。 这种形式的通信与传统的 HTTP、TCP 所不同。传统的 HTTP 请求—响应协议是无法实现实时通信的&#xff0c;也就是说&#xff0c;只能由客户端向服务端发送请求…

前端Web开发,HTML,css,JavaScript

web浏览器响应流程&#xff0c;及技术不同的浏览器&#xff0c;内核不同&#xff0c;对于相同的前端代码解析的效果会存在差异web标准&#xff0c;三个组成部分 HTML&#xff1a;负责网页的结构&#xff08;页面元素和内容&#xff09;CSS&#xff1a;负责页面的表现&#xff0…

VC调试方法大全

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

文章目录 198.打家劫舍213.打家劫舍II337.打家劫舍III 198.打家劫舍 题目链接&#xff1a;代码随想录 解题思路&#xff1a; 1.dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i] 只是考虑&#xff0c;不一定偷 2.递推…

【STM32CubeMX】F103外部中断

前言 本文记录下我学习STM32CubeMX时的流程&#xff0c;方便以后回忆。系统板是基于STM32F103C6T6。本章记录外部中断。 步骤 该实验步骤以&#xff0c;配置PA1为外部中断下降沿触发事件&#xff0c;在触发事件后点亮板载PC13LED灯 时钟配置和生成文件配置之类的&#xff0c;其…

3.6 cache存储器

学习步骤&#xff1a; 我会采取以下几个步骤来学习Cache存储器&#xff1a; 确定学习目标&#xff1a;Cache存储器作为一种高速缓存存储器&#xff0c;通常用于提高计算机系统的运行效率。因此&#xff0c;我需要明确学习Cache存储器的目的&#xff0c;包括了解其原理、结构和…

No.054<软考>《(高项)备考大全》【冲刺8】《软考之 119个工具 (6)》

《软考之 119个工具 &#xff08;6&#xff09;》 99.应急应对策略:100.风险在评估:101.风险审计:102.偏差和趋势分析:103.技术绩效测量:104.自制或外购分析:105.市场调研:106.投标人会议:107.建议书评价技术:108.独立核算:109.广告:110.采购谈判:111.合同变更控制系统:112.采购…

定位图像坐标系和角度误区

坐标系和角度的常见误区 在学习halcon的时候.常常看文档的时候,会有一些地方比较疑感有些常用的地方有细微的差距,一不留意。就会导致计算的数据出错 常见的误区就在坐标系和角度 halcon的帮助情况 存在Px,Py 大家不要被搞混乱 Px -> Row Py-> Column 很多人定位项…

C语言——字符串及字符函数的介绍

C语言——字符串及字符函数的介绍 一、字符函数1.strlen1.1strlen的使用1.2strlen的三种模拟实现1.2.1计数器实现strlen函数1.2.2递归方法实现strlen函数1.2.3指针方法实现strlen函数 1.3 注意事项 2.strcpy2.1strcpy使用2.2strcpy的模拟实现2.3strcpy的注意事项 3.strcat3.1st…

【小样本分割 2022 ECCV】SSP

文章目录 【小样本分割 2022 ECCV】SSP摘要1. 介绍2. 相关工作3. 自支持小样本语义分割3.1 动机3.2 自支持原型-SSM3.3 自适应自支持背景原型-ASBP3.4 自支持匹配-SSL 3. 代码 【小样本分割 2022 ECCV】SSP 论文题目&#xff1a;Self-Support Few-Shot Semantic Segmentation 中…

SpringCloud 微服务系列——【Gateway、Config组件使用】

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

第二十三章 材质

3D模型主要是通过材质&#xff08;Material&#xff09;和贴图&#xff08;Texture&#xff09;来表现其精美的外表&#xff0c;说白了就是一张“画皮”而已。我们之前的DirectX课程中介绍过材质&#xff0c;它实际就是对光的反射率&#xff0c;这样简单的设置并不能展现3D模型…