Linux C——网络编程

本案例运行环境:Ubuntu 12.04.1 LTS
1、基本概念

网络的七层模型:

  1.     物理层
  2.     数据链路层
  3.     网络层
  4.     传输层
  5.     会话层
  6.     表示层
  7.     应用层

    其中:1、2、3层主要面向通过网络端到端的数据流, 4、5、6、7层定义了程序的功能
    
TCP/IP的四层模型

  •     应用层:应用层和传输层之间的接口由端口号和套接字所定义,包含Telnet和文件传输协议(FTP)
  •     传输层:端到端的数据传输,从一个应用传输到它的远程对等实体,包含UDP,TCP协议
  •     网络层:网络上传输的基本信息单位,有IP、ICMP、ARP、RARP等
  •     网络接口层:也叫链路层,数据链路层,实际网络硬件接口

    
TCP协议
    传输控制协议,为应用程序提供可靠的通信连接,他具有可靠的、面向连接的、不容易拥塞的、具有流量控制功能的协议。适用于一次传输大批量数据的情况并可要求得到相应的应用程序提供全双工可交付服务,采取许多机制确保端到端结点之间的可靠数据传输,如采用序列号、确认重传和滑动窗口
    TCP具有重传功能的积极确认技术
    确认:指接收端在正确收到报文后向接收端发一个确认(ACK)信息。发送端将每个已发送的报文备份在自己的缓冲区,在收到相应的确认之前不会丢弃保存的报文段
    积极:发送端在每一个报文发送完成后,同时启动一个定时器,若加入定时器的定时期满而关于报文段的确认信息还没有达到,则认为已经丢失并主动重发
    三次握手
        第一次握手:客户端将syn(同步)设置为1,同时产生一个随机数seq发送给服务端
        第二次握手:服务端接收到报文,将syn=1,产生随机数seq根ack=端口seq+1的确认报文发送给客户端
        第三次握手:客户端接受到服务端报文,同时发送一个确认报文ack=服务端seq+1
        
UDP协议
    用户数据报协议,一种无连接协议。它适用于对数据可靠性的要求不那么高,实时性高、网络状况良好的情况下

2、套接字

套接字是操作系统内核中的一个数据结构,他是网络中的结点进行相互通信的门户,是网络进程的ID。 网络通信本质上是进程间通信(不同计算机上的进程间通信) 套接字中包含端口号,而在一个计算机中,一个端口号一次只能分配给一个进程。从而精确到不同计算机上进程间通信

2.1 Socket

概念
    它是一种特殊的I/O接口,也是一种文件描述符。每一个Socket用一个半相关描述{协议、本地地址、本地端口}来表示;一个完整的套接字则用一个相关描述{协议、本地地址、本地端口、远程地址、远程端口}

类型

  •     流式Socket:用于TCP通信,流式套接字提供可靠的、面向连接的通信流
  •     数据报Socket:用于UDP通信,数据报套接字定义了一种无连接的服务,数据通过相互独立的数据报文进行传输
  •     原始Socket:用于新的网络协议实现的测试,允许对底层协议IP或ICMP进行直接访问
网络编程中基本信息数据结构struct sockaddr{unsigned short sa_family;    /*地址族*/char sa_data[14];            /*14字节的地址协议,包含Socket的IP地址和端口号*/};struct sockaddr_in{short int sin_family;                //地址族,在<netinet/in.h>中。AF_INET表示IPv4,AF_INET6表示IPv6unsigned short int sin_port;        //端口号struct in_addr sin_addr;            //IP地址unsigned char sin_zero[8];          //填充0以保持与struct sockaddr同样大小};struct in_addr{unsigned long int s_addr;  //32位IPv4地址,网络字节序}
2.2 数据存储优先顺序转换
同为小端,异为大端:内低数低,内高数高:小端内低数高,内高数低:大端
​
网络字节序都是大端
​
相互转换的4个函数:htons()、ntohs()、htonl()、ntohl()h:host,主机n:network,网络s:short 16位l:long  32位

在网络编程中端口号和IP地址均要进行顺序转化,IP地址通过地址格式转化会自动变为网络字节序,故若IP地址通过地址格式转换了,就只要将端口号进行转换即可

 函数详解

表头文件#include <netinet/in.h>定义函数unsigned long int htonl(unsigned long int hostlong);
​
函数说明将32位主机字节转换成网络字节返回值返回对应的网络字节序

 综合案例

#include <stdio.h>
#include <netinet/in.h>    
#include <stdlib.h>int main(int argc,char *argv[])
{char port[] = "1000";struct sockaddr_in sockaddr;sockaddr.sin_port = htons(atoi(port));printf("转换前字节序:%x\n",atoi(port));printf("转换后字节序:%x\n",sockaddr.sin_port);return 0;
}

运行结果

linux@ubuntu:~/test$ gcc to.c  //文件名为to.c
linux@ubuntu:~/test$ ./a.out 
转换前字节序:3e8
转换后字节序:e803
2.3 地址格式转换
将点分十进制表示的数值转换成Socket编程时使用的32位网络字节序的二进制值

 函数详解

表头文件#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>定义函数unsigned long int inet_addr(const char* cp);
​
函数说明将参数cp所指的网络地址字符串(以数字和点组成的字符串)转换成二进制数字返回值成功返回对应的网络二进制的数字,失败返回-1
表头文件#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>定义函数int inet_aton(const char* cp,struct in_addr *inp);
​
函数说明将参数cp所指的网络地址字符串(以数字和点组成的字符串)转换成二进制数字,然后存于参数inp所指的in_addr结构中返回值成功返回非0值,失败返回-1
表头文件#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>定义函数char * inet_ntoa(struct in_addr in);
​
函数说明将参数in所指的二进制数字转换成网络地址字符串(以数字和点组成的字符串),然后指向此网络地址字符串的值返回返回值成功返回字符串指针,失败返回NULL

综合案例 

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main(int argc,char *argv[])
{char ip[] = "192.168.0.101";struct in_addr myaddr;         //存储32位IPv4网络字节序的结构体/*inet_aton   网络地址换成二进制数字*/int iRet = inet_aton(ip,&myaddr);printf("%x\n",myaddr.s_addr);/*inet_addr  网络地址换成二进制数字*/myaddr.s_addr = inet_addr(ip);printf("%x\n",myaddr.s_addr);/*inet_ntoa  二进制数字转换成网络地址*/myaddr.s_addr = 0xac100ac4;char* IPv4 = inet_ntoa(myaddr);printf("%s\n",IPv4);return 0;
}

运行结果

linux@ubuntu:~/test$ gcc wl01.c     //文件名叫wl01.c
linux@ubuntu:~/test$ ./a.out 
6500a8c0
6500a8c0
196.10.16.172
3、网络编程

3.1 建立Socket通信

 函数详解 

表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int socket(int domain,int type,int protocol)
​
函数说明用来建立一个新的Socket,也就是向系统注册,通知系统建立一个通信端口domain:指定使用何种地址类型PF_INET/AF_INET:IPv4网络协议PF_INET6/AF_INET6:IPv6网络协议....type:SOCK_STREAM:提供双向连续可信赖的数据流,即TCP连接,支持OOB机制,在所有数据传送前必须使用connect()来建立连线状态SOCK_DGRAM:提供不连续不可信赖的数据包连接SOCK_SEQPACKET:提供连续可信赖的数据包连接SOCK_RAW:提供原始网络协议存取SOCK_RDM:提供可信赖的数据包连接SOCK_PACKET:提供网络驱动程序的直接通信protocol:指定Socket所使用的传输协议编号,通常默认设置为0返回值成功返回Socket处理代码,即通信文件指针或叫做通信句柄,失败返回-1

常用实例

/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
int sockfd;
sockfd = socket(AF_INET,SOCK_STREAM,0);    //表示建立一个IPv4的地址的TCP连接通信
if(sockfd == -1)
{perror("error!");exit(-1);
}
3.2 绑定地址
表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int bind(int sockfd,struct sockaddr *my_addr,int addrlen);
​
函数说明用于对Socket进行定位给参数sockfd的Socket绑定IP地址和端口号等。IP地址端口号等参数my_addr指向一sockaddr结构*my_addr:sockaddr结构addrlen:sockaddr的结构长度返回值成功返回0,失败返回-1

常用实例

/********************************************************************此为经常使用的用法,并不是一个完整的可以编译的源代码                  *绑定地址的步骤为:                                                                *1.定义一个struct sockaddr_in类型的变量                            *2.将变量内数据清空                                                *3.为三个变量sa_family 地址族,sin_port 端口号,sin_addr IP地址赋值  *4.地址绑定******************************************************************/struct sockaddr_in my_addr;
memset(&my_addr,0,sizeof(struct sockaddr));
//或 bzero(&my_addr,sizeof(struct sockaddr));my_addr.sa_family = AF_INET;   //采用IPv4网络协议
my_addr.sin_port = htons(atoi("8080"));  //表示端口号为8080,通常是一个大于1024的端口值
//htons() 用来将指定的16位hostshort转换成网络字节序,本质上就是将存在主机上的两个字节内数据的数据转化成网络字节顺序
//atoi() 用于将数字字符串转换成int型数字,若是一个整数,则不需要这个函数进行转换//inet_addr() 用于将点分十进制的IP地址字符串转换成二进制数字,若位INADDR_ANY表示自动填充本机IP地址
my_addr.sin_addr = inet_addr("192.168.1.1");//sockfd为上一步创建的通信句柄(通信文件指针),参数2为强制类型转换,因为第二个参数的类型是strcut sockaddr,往结构体内填充具体数据又要用struct sockaddr_in这个结构体,故需要强制类型转换,为什么不直接使用struct sockaddr_in这个结构体呢,因为使用IPv4和IPv6所需要的字长是不一样的
if(bind(sockfd,(struct sockaddr *)&myaddr,sizeof(struct sockaddr)) == -1)
{perror("bind error!");
}
3.3 监听

  函数详解 

表头文件#include <sys/socket.h>定义函数int listen(int sockfd,int backlog);
​
函数说明用于等待连接,用来等待参数sockfd的Socket连线。backlog:指定同时能处理的最大连接要求返回值成功返回0,失败返回-1注意listen()只适用于SOCK_STREAM或SOCK_SEQPACKET的Socket类型。若为AF_INET,则参数backlog的最大值可为128

 常用实例

/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
if(listen(sockfd,10) == -1)
{perror("listen");close(sockfd);exit(-1);
}
3.4 接受请求

 函数详解  

表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int accept(int sockfd,struct sockaddr *addr,int *addrlen);
​
函数说明用于接收Socket连线,接收参数sockfd的Socket连线,参数sockfd必须经过bind()和listen()处理过当有连线进来时,accept()会返回新的Socket处理代码,之后的数据传送于读取就由新的Socket处理,原来参数sockfd的Socket能继续使用accept()来接收新的连线要求,连线成功后,参数sddr所指的结构会被系统填入远程主机的地址数据addrlen为scokaddr的结构长度返回值成功返回新的Socket处理代码,也就是一个新的通信句柄,后续的数据传输和读取都要通过新的这个句柄进行操作,原来的句柄继续使用,继续监听其他客户机的请求,失败返回-1

  常用实例

/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
struct sockaddr_in clientaddr;     //定义一个变量,用于存储远程主机的地址数据
memset(&clientaddr,0,sizeof(struct sockaddr));   //清空结构体int new_sockfd = accept(sockfd,(struct sockaddr*)&clientaddr,sizeof(struct sockaddr));if(new_sockfd == -1)
{perror("accept error!");close(sockfd);exit(-1);
}
3.5 连接服务器

 函数详解  

表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int connect(int sockfd,struct sockaddr *serv_addr,int addrlen);
​
函数说明用于接收Socket连线,将参数sockfd的Socket连至参数serv_addr指定的网络地址addrlen:sockaddr的结构长度返回值成功返回0,失败返回-1

  常用实例

/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
struct sockaddr_in seraddr;     //定义一个变量,用来存储所需连接的服务器地址信息
memset(&seraddr,0,sizeof(struct sockaddr));
seraddr.family = AF_INET;                              //IPv4协议
seraddr.sin_port = htons(10000);                       //服务器的端口号
seraddr.sin_addr.s_addr = inet_addr("192.168.2.19");   //服务器的IP地址if(connect(sockfd,(struct sockaddr*)&sockaddr_in,sizeof(struct sockaddr)) == -1)
{perror("connect error!");close("sockfd");exit(-1);
}
3.6 发送数据

 函数详解  

表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int send(int s,const void *msg,int len,unsigned int falgs);
​
函数说明用于通过Socket传送数据,将数据由指定的Socket传给对方主机。s:已建立好连接的Socketmsg:欲指向连线的数据内容len:数据长度flags:一般设为0,也有其他数值定义,可自行查询返回值成功返回实际传送出去的字符数,失败返回-1
表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int sendto(int s,const void *msg,int len,unsigned int falgs,const struct sockaddr* to,int tolen);
​
函数说明用于通过Socket传送数据,将数据由指定的Socket传给对方主机。s:已建立好连接的Socketmsg:欲指向连线的数据内容len:数据长度flags:一般设为0,也有其他数值定义,可自行查询to:欲传送的网络地址tolen:sockaddr的结果长度返回值成功返回实际传送出去的字符数,失败返回-1

   常用实例

/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
char data[256] = "hello C.";
if(send(new_sockfd,data,sizeof(data),0) == -1)
{perror("send error!");close(new_sockfd);close("sockfd");exit(-1);
} 
3.7 接收数据

 函数详解  

表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int recv(int s,void *buf,int len,unsigned int falgs);
​
函数说明用于通过Socket接收数据,将接收由指定的Socket传来的数据。s:已建立好连接的Socketbuf:存储数据的内存空间地址len:;可接收数据最大长度flags:一般设为0MSG_OOB:接收以out-of-band送出的数据MSG_PEEK:返回来的数据并不会在系统内删除,若再次调用recv()会返回相同的数据内容MSG_WAITALL:强迫接收到len大小的数据后才能返回,除非有错误发生MSG_NOSIGNAL:此操作不愿被SIGPIPE信号中断返回值成功返回接收到的字符数,失败返回-1
表头文件#include <sys/types.h>#include <sys/socket.h>定义函数int recvfrom(int s,void *buf,int len,unsigned int falgs,struct sockaddr* from,int *fromlen);
​
函数说明用于通过Socket接收数据,将接收由指定的Socket传来的数据。s:已建立好连接的Socketbuf:存储数据的内存空间地址len:;可接收数据最大长度flags:一般设为0MSG_OOB:接收以out-of-band送出的数据MSG_PEEK:返回来的数据并不会在系统内删除,若再次调用recv()会返回相同的数据内容MSG_WAITALL:强迫接收到len大小的数据后才能返回,除非有错误发生MSG_NOSIGNAL:此操作不愿被SIGPIPE信号中断from:指定欲传送的网络地址fromlen:sockaddr的结构长度返回值成功返回接收到的字符数,失败返回-1
/*此为经常使用的用法,并不是一个完整的可以编译的源代码*/
char sock_buf[256] = {0};
if(recv(new_sockfd,buf,sizeof(buf),0) == -1)
{perror("recv error");close(new_sockfd);exit(-1);
}
puts(buf);
3.8 简单综合案例

服务器端:server.c

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc,char *argv[])
{int sockfd;int new_sockfd;char data[512];char data_buf[512];struct sockaddr_in server_addr;memset(&server_addr,0,sizeof(struct sockaddr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(10000);server_addr.sin_addr.s_addr = inet_addr("192.168.124.177");//建立通信if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("sockfd error.");exit(-1);}//绑定地址if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) < 0){perror("bind error.");close(sockfd);exit(-1);}printf("服务器启动\n");//监听if(listen(sockfd,10) == -1){perror("sockfd error.");close(sockfd);exit(-1);}new_sockfd = accept(sockfd,NULL,NULL);if(new_sockfd < 0){perror("accept error.");close(sockfd);exit(-1);}while(1){if(recv(new_sockfd,data_buf,sizeof(data_buf),0) < 0){perror("recv error.");close(sockfd);exit(-1);}printf("%s\n",data_buf);sprintf(data,"get data:%s\n",data_buf);if(send(new_sockfd,data,sizeof(data),0) < 0){perror("send error.");close(sockfd);exit(-1);}}return 0;
}

客户端:server.c

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc,char *argv[])
{int sockfd;char data[512];char data_buf[512];struct sockaddr_in server_addr;memset(&server_addr,0,sizeof(struct sockaddr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(10000);server_addr.sin_addr.s_addr = inet_addr("192.168.124.177");if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("sockfd error.");exit(-1);}printf("启动成功\n");if(connect(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) < 0){perror("connect error.");close(sockfd);exit(-1);}printf("连接成功\n");while(1){printf("输入你想要发送的数据:");scanf("%s",data);getchar();if(send(sockfd,data,sizeof(data),0) < 0){perror("send error.");close(sockfd);exit(-1);}if(recv(sockfd,data_buf,sizeof(data_buf),0) < 0){perror("recv error.");close(sockfd);exit(-1);}printf("%s",data_buf);}return 0;
}

 编译代码

linux@ubuntu:~/test$ gcc server.c -o server -Wall
linux@ubuntu:~/test$ gcc client.c -o client -Wall

运行结果

/*服务器端*/
linux@ubuntu:~/test$ ./server
服务器启动
nihao
dajiahao
shijiediyi
shijiediyi
shijiediyi/*客户端*/
linux@ubuntu:~/test$ ./client 
启动成功
连接成功
输入你想要发送的数据:nihao 
get data:nihao
输入你想要发送的数据:dajiahao
get data:dajiahao
输入你想要发送的数据:shijiediyi 
get data:shijiediyi
输入你想要发送的数据:^C

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

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

相关文章

抱歉占用公共资源,大家别猜啦,我们在一起了@Yaker

家人们上午好呀 这里是超绝脱单牛一枚 没错&#xff0c;我和Yaker有一个孩子&#xff08;bushi 今天我们的孩子YakLang来给大家介绍介绍&#xff0c;ta对块作用域的处理方式 在编程中&#xff0c;作用域&#xff08;Scope&#xff09;指的是变量、函数和对象的可访问性和生命…

Java反序列化CC1-TransformedMap链学习

学习参考&#xff1a;Java反序列化CC1链TransformedMap 核心是要学会基本EXP编写&#xff0c;还有怎么找传递链。 链子尾部 这里有一个能反射调用任意类&#xff0c;任意方法的&#xff1a; 以这个漏洞点写EXP&#xff0c;由于这个是public的InvokerTransformer&#xff0c;所…

如何基于scrcpy改造实现大厂一键连招/触摸宏功能(带java源码)-千里马安卓framework实战

背景&#xff1a; 前面公众号文章已经分享过如何实现这种大厂里面一键连招&#xff0c;触摸宏的功能&#xff0c;原理本身是对dev/input下面的节点进行读取保存文件&#xff0c;然后在读取文件进行写入dev/input下面的节点&#xff0c;从而实现了触摸事件的读取和写入&#xf…

初始main方法,标识符和关键字

1. 初识Java的main方法 1.1 main方法示例 public class HelloWorld{public static void main(String[] args){System.out.println("Hello,world");} }图解&#xff1a; 通过上述代码&#xff0c;我们可以看到一个完整的Java程序的结构&#xff0c;Java程序的结构…

C. Lazy Narek (Codeforces Round 972 (Div. 2))

C. Lazy Narek 思路: 动态规划 dp dp[i] 表示 目前寻找的字符下标为i 时的最大分数&#xff08;<i<4&#xff09; 从前往后遍历字符串&#xff0c;每个字符串找5次&#xff0c;找完后把dp取max 注意找的过程中不能修改原dp数组&#xff0c;因为这5次查找是并行的&#x…

STM32引脚输入

文章目录 前言一、看原理图二、开始编程1.开启时钟2.配置GPIOA.0 上拉输入3.读取 GPIOA.0 引脚 GPIOA_IDR 0位上是1&#xff08;按键松开&#xff09;&#xff0c;输入就是高电平&#xff0c;否则就是低电平&#xff08;按键按下&#xff09; 三、完整程序四 测试效果总结 前言…

故障诊断 | 基于双路神经网络的滚动轴承故障诊断

故障诊断 | 基于双路神经网络的滚动轴承故障诊断 目录 故障诊断 | 基于双路神经网络的滚动轴承故障诊断效果一览基本介绍程序设计参考资料效果一览 基本介绍 基于双路神经网络的滚动轴承故障诊断 融合了原始振动信号 和 二维信号时频图像的多输入(多通道)故障诊断方法 单路和双…

快速生成应用:AI大模型与低代码平台如何无缝结合提升效率?

引言&#xff1a;数字化时代的开发挑战 在数字化转型的浪潮中&#xff0c;快速响应市场需求已成为企业的核心竞争力。AI大模型与低代码平台的结合&#xff0c;为应用开发提供了一条更加智能、快速的路径。通过自动代码生成、智能推荐和持续优化&#xff0c;这一无缝结合大幅提升…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-19

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-19 1. SAM4MLLM: Enhance Multi-Modal Large Language Model for Referring Expression Segmentation Authors: Yi-Chia Chen, Wei-Hua Li, Cheng Sun, Yu-Chiang Frank Wang, Chu-Song Chen SAM4MLLM: 增强多模…

21 基于51单片机的隧道车辆检测系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 以AT89C51单片机为控制核心&#xff0c;实现对隧道环境的监测。采用模块化设计&#xff0c; 共分以下几个功能模块&#xff1a; 单片机最小系统模块、电源模块、气体传感模块、和显示模块等。 通过…

在电脑中增加一个新盘

找到此电脑右击找到管理点进去 找到磁盘管理点进去 找到D盘&#xff0c;点击D盘然后右击找到压缩卷点击&#xff0c;之后按照自己的意愿分盘容量 然后就一直点下一页 返回去就能看到新加卷F盘了 在此电脑中也可以查看 完成

ToB项目身份认证(一):基于目录的用户管理、LDAP和Active Directory简述

在ToB的项目里&#xff0c;公司部门之间是树状的关系&#xff0c;成员结构也类似。由于windows的使用范围很广&#xff0c;尤其是在企业里&#xff0c;所以它集成的Active Directory域服务往往企业应用需要兼容的。 什么是基于目录的用户管理&#xff1f; 基于目录的用户管理…

双十一快来了!什么值得买?分享五款高品质好物~

双十一大促再次拉开帷幕&#xff0c;面对众多优惠是否感到选择困难&#xff1f;为此&#xff0c;我们精心筛选了一系列适合数字生活的好物&#xff0c;旨在帮助每一位朋友都能轻松找到心仪之选。这份推荐清单&#xff0c;不仅实用而且性价比高&#xff0c;是您双十一购物的不二…

cc2530使用(SmartRF Flash Programmer)烧录hex固件

1图标 2IAR生成HEX文件 2-1勾选他 2-2生成对应的文件&#xff08;勾选他并改后缀&#xff09; &#xff08;选择他&#xff09; 点击OK即可 3&#xff08;选择文件&#xff0c;插入板子&#xff08;会显示对应的板子&#xff09;&#xff0c;烧录即可&#xff09;

LeetcodeTop100 刷题总结(二)

LeetCode 热题 100&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 文章目录 八、二叉树94. 二叉树的中序遍历&#xff08;递归与非递归&#xff09;补充&#xff1a;144. 二叉树的前序遍历&#xff08;递归与非递归&#xff09;补充&#xff1a;145. 二叉树的后序遍…

注册商标的有关流程

注册商标的有关流程 在商业活动中&#xff0c;商标作为企业品牌的重要组成部分&#xff0c;不仅代表着企业的形象和信誉&#xff0c;更是企业资产的重要部分。因此&#xff0c;了解并遵循注册商标的流程&#xff0c;对于保护企业的合法权益至关重要。 一、确定商标注册范围并进…

大模型学习方向不知道的,看完这篇学习思路好清晰!!

入门大模型并没有想象中复杂&#xff0c;尤其对于普通程序员&#xff0c;建议采用从外到内的学习路径。下面我们通过几个步骤来探索如何系统学习大模型&#xff1a; 1️⃣初步理解应用场景与人才需求 大模型的核心应用涵盖了智能体&#xff08;AI Agent&#xff09;、微调&…

【TPAMI 2024】告别误差,OPAL算法如何让光场视差估计变得轻而易举?

题目&#xff1a;OPAL: Occlusion Pattern Aware Loss for Unsupervised Light Field Disparity Estimation OPAL&#xff1a;面向无监督光场视差估计的遮挡模式感知损失 作者&#xff1a;Peng Li; Jiayin Zhao; Jingyao Wu; Chao Deng; Yuqi Han; Haoqian Wang; Tao Yu 摘要…

一个永久的.NET渗透工具和知识仓库

01前言 为了更好地应对基于.NET技术栈的风险识别和未知威胁&#xff0c;.NET安全攻防帮会从创建以来一直聚焦于.NET领域的安全攻防技术&#xff0c;定位于高质量安全攻防社区&#xff0c;也得到了许多师傅们的支持和信任&#xff0c;通过帮会深度连接入圈的师傅们&#xff0c;…

计算机毕业设计推荐-基于PHP的律所预约服务管理系统

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、基于PHP的律…