《3.linux应用编程和网络编程-第9部分-3.9.linux网络编程实践》3.9.6_7.soekct实践编程1_2

news2024/10/7 12:18:32

概念:端口号,实质就是一个数字编号,用来在我们一台主机中(主机的操作系统中)唯一的标识一个能上网的进程端口号和IP地址一起会被打包到当前进程发出或者接收到的每一个数据包中。每一个数据包将来在网络上传递的时候,内部都包含了发送方和接收方的信息(就是IP地址和端口号),所以IP地址和端口号这两个往往是打包在一起不分家的。

IP 地址用来精确到 那一台 电脑

端口号:用来 精确 到这一台 电脑 某一个进程

3.9.6.1、服务器端程序编写
(1)socket : 建立一个网络连接
(2)bind : 把我当前的 IP 地址 和 端口号  和 socket 绑定起来 
(3)listen : 监听
(4)accept,返回值是一个fd,accept正确返回就表示我们已经和前来连接我的客户端之间建立了一个TCP连接了,以后我们就要通过这个连接来和客户端进行读写操作,读写操作就需要一个fd,这个fd就由accept来返回了。
注意:socket返回的fd叫做监听fd,是用来监听客户端的,不能用来和任何客户端进行读写accept返回的fd叫做连接fd,用来和连接那端的客户端程序进行读写。
 

3.9.9.socket编程实践4
3.9.9.1、自定义应用层协议第一步:规定发送和接收方法
(1)规定连接建立后由客户端主动向服务器发出1个请求数据包,然后服务器收到数据包后回复客户端一个回应数据包,这就是一个通信回合
(2)整个连接的通信就是由N多个回合组成的。

程序 有两个 .c 文件 服务器程序server.c  ,  和 客户端 程序 client.c

服务器程序server.c 

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


#define SERPORT 6003
#define SERADDR "192.168.80.128 " /* 我的电脑做服务器  ubuntu 下 ifconfig 得到的 IP地址 */
#define BACKLOG 10

char recvbuf[100]={0};






int main(void)
{
	int sockfd = -1;  /* 定义一个接收 socket 文件描述符(socket 的返回值) */
	
	int ret = -1;/* 定义一个接收 bind (bind 的返回值) */
	
	int clifd = -1;  /* 定义一个接收 accept (accept的返回值) */
	
	struct sockaddr_in seraddr = {0}; /* 定义一个bind 第二个参数(输入型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	struct sockaddr_in cliaddr = {0}; /* 定义一个accept 第二个参数(输出型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	socklen_t len = 0;
	
	/* 1 . 先 socket  打开文件描述符 */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	printf("sockfd = %d \n", sockfd);
	
	/* 2 . bind 绑定sockfd 和当前电脑的 IP地址 和端口号 */
	seraddr.sin_family = AF_INET;  /* 设置 地址族为 IPV4 */
	seraddr.sin_port = htons(SERPORT);           /* 服务器端口号  htons 当前电脑 字节序 转成 网络 字节序 16位 */
	seraddr.sin_addr.s_addr = inet_addr(SERADDR);   /* 设置 IP地址 */
	ret = bind(sockfd, (const struct sockaddr *)&seraddr, sizeof(seraddr));
	if(ret < 0)
	{
		perror("bind");
		return -1;
	}
	printf("bind success \n");
	
	/* 3 .  listen ,监听 端口号 */
	ret = listen(sockfd, BACKLOG); 
	if(ret < 0)
	{
		perror("listen");
		return -1;
	}
	
	printf("服务器开始监听 \n");
	
	/* 4 .  accept 阻塞等待 客服端来连接服务器 */	
	clifd = accept(sockfd,(struct sockaddr *)&cliaddr,  &len);/* 阻塞等待 客服端来连接服务器  */
	printf("客户端 已连接服务器 clifd = %d \n",clifd);  /*accept返回的fd叫做连接fd,用来和连接那端的客户端程序进行 读写。 */
	
	
	/* 5 .  建立连接后 就可以通讯了 */	
#if 0
	ret = recv(clifd, recvbuf,sizeof(recvbuf),0); /* recv 接收出错会返回 -1 */	
	printf("成功接收了 %d 个字节\n",ret);
	printf("client发送的内容是 %s  \n",recvbuf);
#endif
	while(1)
	{
		/* 1.回合第一步, 服务器接收 */	
		ret = recv(clifd, recvbuf,sizeof(recvbuf),0); /* recv 接收出错会返回 -1 */	
		printf("client发送的内容是 %s  \n",recvbuf);
		memset(recvbuf,0,sizeof(recvbuf));
		
		/* 2.服务器机箱客户 数据包 */	
			
			
		/* 3.回合第三步, 回复客户端  */
		ret = send(clifd, "ok",2,0); /* recv 接收出错会返回 -1 */	
	}

	
	return 0;
}




/*************************************************************
3.9.4.5、表示IP地址相关数据结构
(1)都定义在 netinet/in.h
(2)struct sockaddr,这个结构体是网络编程接口中用来表示一个IP地址的,注意这个IP地址是不区分IPv4和IPv6的(或者说是兼容IPv4和IPv6的)
(3)typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型
(4)struct in_addr
  {
    in_addr_t s_addr;
  };
(5)struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);    宏定义 :这个是看 是IPV4 还是 IPV6  
    in_port_t sin_port;                   端口号
    struct in_addr sin_addr;          	IP地址

  
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };
(6)struct sockaddr			这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。在实际编程中这个结构体会被一个struct sockaddr_in或者一个struct sockaddr_in6所填充。
 const struct sockaddr *address 就等同于  struct sockaddr_in



*******************************************************************/

客户端 程序 client.c

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

/* 客户端端口 号 可以自己分配的,只有 和 服务器的 端口号 一直才能连接上 服务器 */
 
#define SERADDR  "192.168.80.128 " /* 服务器给我们 开放的 IP 地址 和 端口号 */
#define SERPORT  6003
#define BACKLOG 10

char sendbuf[100]={0};
char recvbuf[100];



int main(void)
{
	int sockfd = -1;  /* 定义一个接收 socket 文件描述符(socket 的返回值) */
	int ret = -1;/* 定义一个接收 bind (bind 的返回值) */
	
	struct sockaddr_in seraddr = {0}; /* 定义一个connect 第二个参数(输入型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	
	/* 1 . 先 socket  打开文件描述符 */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	printf("sockfd = %d \n", sockfd);
	
	
	/* 2. connect  */
	seraddr.sin_family = AF_INET;  /* 设置 地址族为 IPV4 */
	seraddr.sin_port = htons(SERPORT);           /* 服务器端口号  htons 当前电脑 字节序 转成 网络 字节序 16位 */
	seraddr.sin_addr.s_addr = inet_addr(SERADDR);   /* 设置 IP地址 */
	ret = connect(sockfd,(const struct sockaddr *)&seraddr, sizeof(seraddr));
	
	if(ret < 0)
	{
		perror("connect");
		return -1;
	}
	printf("成功建立连接 \n");
	
	/*  建立连接后 就可以通讯了 */	
#if 0	
	strcpy(sendbuf,"hello world");
	ret = send(sockfd,sendbuf,strlen(sendbuf), 0);
	printf("发送了 %d 个字符 \n",ret);
#endif
	while(1)
	{
		/*  1. 客户端 首先给服务器 发送数据包 */	
		printf("请输入要发送的内容\n");
		scanf("%s",sendbuf);
		//printf("刚才输入的是 %s \n",sendbuf);
		ret = send(sockfd,sendbuf,strlen(sendbuf), 0);
		printf("发送了多少个字节 %d \n",ret);
		
		/* 2.回合第2步,客户端 接收 服务器的回复  */
		memset(recvbuf,0,sizeof(recvbuf));	
		ret = recv(sockfd, recvbuf,sizeof(recvbuf),0); /* recv 接收出错会返回 -1 */	
		printf("接收到服务器 发送的内容是 %s  \n",recvbuf);
		
		/* 3.回合第3步,客户端 解析 服务器的回复,在做下一步定夺  */
		
	}
	
	return 0;
}



make 

all:
	gcc server.c -o ser
	gcc client.c -o cli

clean:
	rm ser cli *.o -rf

运行结果:

 

 

3.9.9.2、自定义应用层协议第二步:定义数据包格式

服务器程序server.c 

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


#define SERPORT 6003
#define SERADDR "192.168.80.128 " /* 我的电脑做服务器  ubuntu 下 ifconfig 得到的 IP地址 */
#define BACKLOG 10

char recvbuf[100]={0};

#define CMD_REGISTER  1001 /*注册学生信息 */
#define CMD_CHECK     1002  /*检查 学生信息 */
#define CMD_GETINFO   1003  /*获取 学生信息 */

#define STAT_OK    30
#define STAT_ERR   31

typedef struct commu
{
	char name[20]; /* 学生姓名 */
	int age;  /* 学生年龄 */
	int cmd; /*命令码*/
	int stat; /*状态信息, */
	
}info;






int main(void)
{
	int sockfd = -1;  /* 定义一个接收 socket 文件描述符(socket 的返回值) */
	
	int ret = -1;/* 定义一个接收 bind (bind 的返回值) */
	
	int clifd = -1;  /* 定义一个接收 accept (accept的返回值) */
	
	struct sockaddr_in seraddr = {0}; /* 定义一个bind 第二个参数(输入型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	struct sockaddr_in cliaddr = {0}; /* 定义一个accept 第二个参数(输出型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	socklen_t len = 0;
	
	/* 1 . 先 socket  打开文件描述符 */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	printf("sockfd = %d \n", sockfd);
	
	/* 2 . bind 绑定sockfd 和当前电脑的 IP地址 和端口号 */
	seraddr.sin_family = AF_INET;  /* 设置 地址族为 IPV4 */
	seraddr.sin_port = htons(SERPORT);           /* 服务器端口号  htons 当前电脑 字节序 转成 网络 字节序 16位 */
	seraddr.sin_addr.s_addr = inet_addr(SERADDR);   /* 设置 IP地址 */
	ret = bind(sockfd, (const struct sockaddr *)&seraddr, sizeof(seraddr));
	if(ret < 0)
	{
		perror("bind");
		return -1;
	}
	printf("bind success \n");
	
	/* 3 .  listen ,监听 端口号 */
	ret = listen(sockfd, BACKLOG); 
	if(ret < 0)
	{
		perror("listen");
		return -1;
	}
	
	printf("服务器开始监听 \n");
	
	/* 4 .  accept 阻塞等待 客服端来连接服务器 */	
	clifd = accept(sockfd,(struct sockaddr *)&cliaddr,  &len);/* 阻塞等待 客服端来连接服务器  */
	printf("客户端 已连接服务器 clifd = %d \n",clifd);  /*accept返回的fd叫做连接fd,用来和连接那端的客户端程序进行 读写。 */
	
	
	/* 5 .  建立连接后 就可以通讯了 */	
#if 0
	ret = recv(clifd, recvbuf,sizeof(recvbuf),0); /* recv 接收出错会返回 -1 */	
	printf("成功接收了 %d 个字节\n",ret);
	printf("client发送的内容是 %s  \n",recvbuf);
#endif
	while(1)
	{
		/* 1.回合第一步, 服务器接收 */	
		info st;
		
		ret = recv(clifd, &st,sizeof(info),0); /* recv 接收出错会返回 -1 */	
		
		/* 2.服务器解析 客户 数据包 */	
		if(st.cmd == CMD_REGISTER)
		{
			printf("用户要注册学生信息 \n");
			printf("学生姓名:%s, 学生年龄: %d \n",st.name, st.age);
			
			/* 3.回合第三步, 回复客户端  */
			st.stat = STAT_OK;
			ret = send(clifd, &st,sizeof(info),0); /* recv 接收出错会返回 -1 */	
			
		}
		
		
		if(st.cmd == CMD_CHECK)
		{
		}
		
	}

	
	return 0;
}




/*************************************************************
3.9.4.5、表示IP地址相关数据结构
(1)都定义在 netinet/in.h
(2)struct sockaddr,这个结构体是网络编程接口中用来表示一个IP地址的,注意这个IP地址是不区分IPv4和IPv6的(或者说是兼容IPv4和IPv6的)
(3)typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型
(4)struct in_addr
  {
    in_addr_t s_addr;
  };
(5)struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);    宏定义 :这个是看 是IPV4 还是 IPV6  
    in_port_t sin_port;                   端口号
    struct in_addr sin_addr;          	IP地址

  
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };
(6)struct sockaddr			这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。在实际编程中这个结构体会被一个struct sockaddr_in或者一个struct sockaddr_in6所填充。
 const struct sockaddr *address 就等同于  struct sockaddr_in



*******************************************************************/


客户端程序 client.c

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

/* 客户端端口 号 可以自己分配的,只有 和 服务器的 端口号 一直才能连接上 服务器 */
 
#define SERADDR  "192.168.80.128 " /* 服务器给我们 开放的 IP 地址 和 端口号 */
#define SERPORT  6003
#define BACKLOG 10

char sendbuf[100]={0};
char recvbuf[100];

#define CMD_REGISTER  1001 /*注册学生信息 */
#define CMD_CHECK     1002  /*检查 学生信息 */
#define CMD_GETINFO   1003  /*获取 学生信息 */

#define STAT_OK    30
#define STAT_ERR   31

typedef struct commu
{
	char name[20]; /* 学生姓名 */
	int age;  /* 学生年龄 */
	int cmd; /*命令码*/
	int stat; /*状态信息, */
	
}info;


int main(void)
{
	int sockfd = -1;  /* 定义一个接收 socket 文件描述符(socket 的返回值) */
	int ret = -1;/* 定义一个接收 bind (bind 的返回值) */
	
	struct sockaddr_in seraddr = {0}; /* 定义一个connect 第二个参数(输入型参数) 这个结构体是网络编程接口中用来表示一个IP地址的 */
	
	
	/* 1 . 先 socket  打开文件描述符 */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	printf("sockfd = %d \n", sockfd);
	
	
	/* 2. connect  */
	seraddr.sin_family = AF_INET;  /* 设置 地址族为 IPV4 */
	seraddr.sin_port = htons(SERPORT);           /* 服务器端口号  htons 当前电脑 字节序 转成 网络 字节序 16位 */
	seraddr.sin_addr.s_addr = inet_addr(SERADDR);   /* 设置 IP地址 */
	ret = connect(sockfd,(const struct sockaddr *)&seraddr, sizeof(seraddr));
	
	if(ret < 0)
	{
		perror("connect");
		return -1;
	}
	printf("成功建立连接 \n");
	
	/*  建立连接后 就可以通讯了 */	
#if 0	
	strcpy(sendbuf,"hello world");
	ret = send(sockfd,sendbuf,strlen(sendbuf), 0);
	printf("发送了 %d 个字符 \n",ret);
#endif
	while(1)
	{
		/*  1. 客户端 首先给服务器 发送数据包 */	
		info st1;
		printf("请输入学生姓名\n");
		scanf("%s",st1.name);
		printf("请输入学生年龄\n");
		scanf("%d",&st1.age);
		st1.cmd = CMD_REGISTER;
		//printf("刚才输入的是 %s \n",sendbuf);
		ret = send(sockfd,&st1,sizeof(info), 0);
		printf("发送了多少个字节 %d \n",ret);
		
		/* 2.回合第2步,客户端 接收 服务器的回复  */
		memset(&st1,0,sizeof(info));	
		ret = recv(sockfd, &st1,sizeof(info),0); /* recv 接收出错会返回 -1 */	
		
		/* 3.回合第3步,客户端 解析 服务器的回复,在做下一步定夺  */
		if(st1.stat == STAT_OK)
		{
			printf("注册学生信息成功 \n");
			printf(" \n");
		}
		else
		{
			printf("注册学生信息失败 \n");
		}
		
		
	}
	
	return 0;
}


运行结果:


3.9.9.3、常用应用层协议:http、ftp······
3.9.9.4、UDP简介

 

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

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

相关文章

人工智能顶会投稿截止时间汇总

一、NeurIPS 1. 会议名称及等级 Annual Conference on Neural Information Processing Systems&#xff08;CCF-A&#xff09;https://dblp.uni-trier.de/db/conf/nips/index.html 2. 投稿时间及接收率 https://neurips.cc/Conferences/2023/CallForPapers#OpenReview 一般…

(Linux)基础命令

帮助文档 公式功能man 命令名访问Linux手册页命令名 – helpinfo 命令名查看命令的功能&#xff0c;来源&#xff0c;选项等whatis 命令名 ls 公式功能ls [选项][目录或文件]对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及…

linux kernel单独编译某项驱动

linux内核经常涉及编译某一项驱动代码的场景&#xff0c;本次以网卡驱动e1000为例说明整个步骤流程。 首先编译内核驱动不必要编译整个内核&#xff0c;但编译的驱动代码必须要和要安装的内核版本保持一致&#xff0c;否则经常会出现无法加载模块。 在编译驱动前&#xff0c;最…

2023年上半年系统集成项目管理工程师成绩什么时候出

一般是考后30个工作日左右&#xff0c;即2023年7月中下旬出成绩的概率比较大&#xff0c;只能耐心等待了&#xff0c;届时软考办官网会发布成绩查询通知。 注意&#xff01;&#xff01;2023年上半年系统集成项目管理工程师成绩查询方法跟以前有点区别&#xff1a; 以前&…

C++入门学习(1)

一&#xff0c;我的第一个C程序 代码&#xff1a; #include<iostream> using namespace std; int main() {cout << "hello world" << endl; } 这是我写的第一篇关于C的博客&#xff0c;上面的程序也是我写的第一个C程序。对于用惯了C语言的我来说…

【GlobalMapper精品教程】062:基于DEM制作仿地飞行DSM文件(适用于精灵4RTK)

仿地飞行指的是无人机根据获取的地形数据调整飞行高度,保持对地的恒定高差。目前,主要有实时仿地、导入高程(高度)数据仿地两种仿地飞行方式。本文讲解基于DEM数字高程模型进行仿地DSM高程文件制作的方案。 文章目录 一、确定外业范围二、下载准备DEM三、仿地DSM制作1. 裁剪…

python VTK vtkImplicitBoolean 布尔切割

VTK中包含可以执行布尔操作的接口有vtkImplicitBoolean&#xff0c;vtkBooleanOperationPolyDataFilter&#xff0c;vtkLoopBooleanPolyDataFilter。 布尔操作包括&#xff1a;布尔加&#xff0c;布尔减和布尔交。 code: #!/usr/bin/env python""" This examp…

不是吧?强大的 vite 居然不支持内 SVG 转 Base64 内嵌?

大家好&#xff0c;我是前端西瓜哥。 诶哟喂&#xff0c;SVG 怎么没内嵌&#xff1f; 最近啊&#xff0c;西瓜哥我用 vite 去给一个项目构建&#xff08;vite build&#xff09;一个应用。打包结果是一个 html 和一些加了哈希的资源。 然后打包出来的文件一看&#xff0c;发…

SpringCloud学习路线(3)—— Eureka注册中心

一、导引 服务调用出现的问题 服务调用采取的请求地址是静态的&#xff0c;当我们使用服务集群时&#xff0c;很容易造成只能调用固定的微服务上的接口。多个提供者&#xff0c;消费者的使用对象无法确定消费者无法得知提供者的状态 二、Eureka注册中心 &#xff08;一&…

加水印用什么软件你知道吗?告诉你加水印的app哪个好用吧

笑笑是一个热爱生活的女孩&#xff0c;她经常会随手拍下生活的瞬间&#xff0c;并且在社交媒体上分享自己的开心时刻。然而&#xff0c;最近她发现自己的照片被未经授权地使用在其他网站和博客上。这让她感到非常生气。为了保护自己的作品权益&#xff0c;她决定寻找一个好用的…

vue3 h函数使用图文教程

序&#xff1a; 1、官方文档地址》渲染函数 & JSX | Vue.js 2、博主微信公众号&#xff1a;“程序员野区”&#xff0c;关注公众号回复“加群&#xff0c;可以进到博主微信群 正文&#xff1a; 别恐惧啊&#xff0c;别一看官方api那边标注的 是进阶api就跳过去&#xff0c…

1ll大学学生信息管理系统系统_学院管理_查询新增或修改删除标准接口_

目录 修订版本 1. 目的 2. 阅读人员 3. 参考文档 ll大学学生信息管理系统系统_学院管理_查询新增或修改删除标准接口 4.1 接口概述 4.2 接口名称 4.3查询学院信息接口标准 4.4新增学院信息接口标准 4.5修改学院信息接口标准 学生信息管理系统系统_学院管理_查询新增或…

【unity细节】分不清楚__世界坐标,自身坐标,Vector3,transform和translate?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐世界坐标系transform和自身坐标Trasform.local和Vector3⭐ 文章目录 ⭐世界坐标…

__builtin_return_address函数

文章目录 一、gcc 内置函数二、__builtin_return_address2.1 简介2.2 代码示例 三、查看函数调用参考资料 一、gcc 内置函数 GCC 内置函数是指 GCC 编译器内置的一些函数&#xff0c;这些函数可以用于实现一些常用的操作&#xff0c;如数学运算、字符串处理、内存管理、调试等…

如何创作小红书化妆品文案,技巧分析!

小红书拥有众多女性用户群。美妆自然成为里面最大的板块&#xff0c;所以不管是护肤品牌&#xff0c;还是相关达人都会进行化妆品类的文案创作。今天从两个方案来探讨下如何创作小红书化妆品文案&#xff0c;技巧分析&#xff01; 一、对品牌输出文案的重点 1. 强调产品特点 向…

牛客周赛 Round 3

游游的7的倍数 思路分析 添加一个数让其为7的倍数。倍数&#xff0c;每7个中必有一个是7的倍数&#xff0c;在末尾添加一个数即可.遍历0-6&#xff0c;满足既可。 时间复杂度 O&#xff08;1&#xff09; 代码 #include<bits/stdc.h> using namespace std; using ll…

毫秒级的 Unix 时间戳,将其转换为日期时间格式,报错,“将 expression 转换为数据类型 int 时出现算术溢出错误”

如果您有一个时间戳值为 1689217823000&#xff0c;表示毫秒级的 Unix 时间戳&#xff0c;您可以将其转换为日期时间格式。在 SQL Server 中&#xff0c;可以使用 DATEADD 和 CONVERT 函数来进行转换。 以下是将该时间戳值转换为日期时间格式的步骤&#xff1a; DECLARE timest…

从零开始学习 Java:简单易懂的入门指南(一)

Java基础语法 1. 人机交互1.1 什么是cmd&#xff1f;1.2 如何打开CMD窗口&#xff1f;1.3 常用CMD命令1.4 CMD练习1.5 环境变量 2. Java概述1.1 Java是什么&#xff1f;1.2下载和安装1.2.1 下载1.2.2 安装1.2.3 JDK的安装目录介绍 1.3 HelloWorld小案例1.3.1 Java程序开发运行…

【矩阵的基本操作】——MatLab基础

目录索引 矩阵的基本操作&#xff1a;转置&#xff1a;矩阵的拼接&#xff1a;*横拼&#xff1a;**竖拼&#xff1a;* 矩阵的索引&#xff1a;取元素&#xff1a;*end():* 取区域&#xff1a;逻辑判断&#xff1a;逻辑取值&#xff1a;find()&#xff1a; 矩阵的基本操作&#…

基于net core2.2的redis秒杀+数据持久化+数据恢复系列(2)

第一篇我们总结了秒杀的整个流程&#xff0c;本篇我们详细介绍下redis的秒杀实现&#xff0c;基于.net core2.2开发。 首先&#xff0c;需要安装redis&#xff0c;因为我在本地测试的&#xff0c;所以安装的windows版本的redis。redis分为服务端和客户端&#xff0c;这个redis…