基于Linux下的TCP编程

2023-11-15

基于Linux的TCP网络编程

一.Linux下TCP编程框架

TCP网络编程的流程包含服务器和客户端两种模式。服务器模式创建一个服务程序,等待客户端用户的连接,接收到用户的连接请求后,根据用户的请求进行处理;客户端模式则根据目的服务器的地址和端口进行连接,向服务器发送请求并对服务器的响应进行数据处理。

1.服务器端程序包括

Ø 建立套接字( socket())

Ø 套接字与端口的绑定(bind())

Ø 设置服务器的侦听连接(listen())

Ø 接收客户端连接(accept())

Ø 接收和发送数据(send(),recv())

Ø 关闭套接字(close())

2.说明

1>套接字初始化过程中,根据用户对套接字的需求来确定套接字的选项。按照用户定义的网络类型,协议类型和具体的协议标号等参数来定以socket()函数。系统根据用户的需求生成一个套接字文件描述符供用户使用。

2>套接字与端口的绑定过程中,将套接字与一个地址结构进行绑定。绑定之后,套接字所代表IP地址和端口地址及协议类型等参数按照绑定值进行操作。

3>由于一个服务器需要满足多个客户端的连接请求,而服务器在某个时间仅能处理有限个数的客户端连接请求,所以服务器需要设置服务器端排队队列的长度。

4>在客户端发送连接请求之后,服务器需要接收客户端的连接,然后才能进行其他的处理。

5>在服务器接收客户端请求之后,可以从套接字文件描述符中读取数据或者向文件描述符发送数据。接收数据后服务器按照定义的规则对数据进行处理,并将结果发送给客户端。

6>当服务器处理完数据,要结束与客户端的通信过程的时候,需要关闭套接字连接

2.客户端程序包括

Ø 建立套接字(socket())

Ø 连接服务器(connect())

Ø 读写网络数据(send(),recv())

Ø 关闭套接字(close())

3.服务器端和客户端程序的区别

客户端程序和服务器端程序不同之处是客户端在建立套接字之后可以不进行地址绑定,而是直接连接服务器端。

服务器端有listen()和accept()两个函数,而客户端不需要这两个函数。

二.基于Linux的TCP套接字函数

1. socket

1> 函数原型:

int socket(int domain,int type,int protocol)

2> 函数功能:

函数socket()用于创建一个套接字描述符。

3> 形参:

Ø domain:用于指定创建套接字所使用的协议族,在头文件

<linux/socket.h>中定义。有时候程序中会使用PF_INET,在头文件中AF_INET和PF_INET的数值是一致的。

常见的协议族如下:

AF_UNIX:创建只在本机内进行通信的套接字。

AF_INET:使用IPv4TCP/IP协议

AF_INET6:使用IPv6 TCP/IP协议

说明:

AF_UNIX只能用于单一的UNIX系统进程间通信,而AF_INET是针对Interne的,因而可以允许在远程主机之间通信。一般把它赋为AF_INET。

Ø type:指明套接子通信的类型,对应的参数如下

SOCK_STREAM:创建TCP流套接字

SOCK_DGRAM:创建UDP数据报套接字

SOCK_RAW:创建原始套接字

Ø protocol:指定某个协议的特定类型

参数protocol通常设置为0,表示通过参数domain指定的协议族和参数type指定的套接字类型来确定使用的协议。当为原始套接字时,系统无法唯一的确定协议,此时就需要使用使用该参数指定所使用的协议。

4> 返回值:执行成功后返回一个新创建的套接字;若有错误发生则返回一个-1,错误代码存入errno中。

5> 举例:调用socket函数创建一个UDP套接字

int sock_fd;

sock_fd = socket(AF_INET,SOCK_DGRAM,0);

if(sock_fd< 0){

perror(“socket”);

exit(1);

}

2. bind

1> 函数原型:

int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen)

2> 函数功能

函数bind()的作用是将一个套接字文件描述符与地址和端口绑定。

3> 形参:

Ø sockfd:sockfd是调用socket函数返回的文件描述符;

Ø addrlen是sockaddr结构的长度。

Ø my_addr: 是一个指向sockaddr结构的指针,它保存着本地套接字的地址(即端口和IP地址)信息。不过由于系统兼容性的问题,一般不使用这个结构,而使用另外一个结构(structsockaddr_in)来代替

4> 套接字地址结构:

(1)struct sockaddr:

结构struct sockaddr定义了一种通用的套接字地址,它在

sys/socket.h 中定义。

struct sockaddr{

unsigned short sa_family;/*地址类型,AF_XXX*/

char sa_data[14];/*14字节的协议地址*/

}

a. sin_family:表示地址类型,对于使用TCP/IP协议进行的网络编程,该值只能是AF_INET.

b. sa_data:存储具体的协议地址。

(2)sockaddr_in

每种协议族都有自己的协议地址格式,TCP/IP协议组的地址格式为结构体struct sockaddr_in,它在netinet/in.h头文件中定义。

structsockaddr_in{

unsigned short sin_family;/*地址类型*/

unsigned short sin_port;/*端口号*/

struct in_addr sin_addr;/*IP地址*/

unsigned char sin_zero[8];/*填充字节,一般赋值为0*/

}

a. sin_family:表示地址类型,对于使用TCP/IP协议进行的网络编程,该值只能是AF_INET.

b. sin_port:是端口号

c. sin_addr:用来存储32位的IP地址。

d. 数组sin_zero为填充字段,一般赋值为0.

e. struct in_addr的定义如下:

structin_addr{

unsigned long s_addr;

}

结构体sockaddr的长度为16字节,结构体sockaddr_in的长度为16字节。可以将参数my_addr的sin_addr设置为INADDR_ANY而不是某个确定的IP地址就可以绑定到任何网络接口。对于只有一IP地址的计算机,INADDR_ANY对应的就是它的IP地址;对于多宿主主机(拥有多个网卡),INADDR_ANY表示本服务器程序将处理来自所有网络接口上相应端口的连接请求

5> 返回值:

函数成功后返回0,当有错误发生时则返回-1,错误代码存入errno中。

6>举例:调用socket函数创建一个UDP套接字

struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/

memset(&serv_addr,0,sizeof(structsockaddr_in));

addr_serv.sin_family= AF_INET;/*协议族*/

addr_serv.sin_port= htons(SERV_PORT);/*本地端口号*/

addr_serv.sin_addr.s_addr= htonl(INADDR_ANY); /*任意本地地址*/
/*套接字绑定*/

if(bind(sock_fd,(structsockaddr *)&addr_serv),sizeof(struct sockaddr_in)) <0)

{

perror(“bind”);

exit(1);

}

3. 监听本地端口listen()

1>函数功能:函数listen()用来初始化服务器可连接队列,服务器处理客户端连接请求的时候是顺序处理的,同一时间仅能处理一个客户端连接。当多个客户端的连接请求同时到来的时候,服务器并不是同时处理,而是将不能处理的客户端连接请求放到等待队列中,这个队列的长度由listen()函数来定义。

2>函数原型:

#includ<sys/socket.h>

int listen(int sockfd,int backlog);

3>形参

Ø sockfd: sockfd是调用socket函数返回的文件描述符

Ø backlog:指定该连接队列的最大长度。如果连接队列已经达到最大,之后的连接请求被服务器拒绝。大多数系统的设置为20,可以将其设置修改为5或者10,根据系统可承受负载或者应用程序的需求来确定。

4>返回值:当listen()函数成功运行时,返回值为0;当运行失败时,它的返回值为-1,错误代码存入errno中。

5>.listen()函数的例子:

#define SERV_PORT 3000

int main(int argc,char *argv[])

{

int sock_fd;

struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/

sock_fd = socket(AF_INET,SOCK_DGRAM,0);

if(sock_fd< 0){

perror(“socket”);

exit(1);

}

memset(&serv_addr,0,sizeof(structsockaddr_in));

addr_serv.sin_family= AF_INET;/*协议族*/

addr_serv.sin_port= htons(SERV_PORT);/*本地端口号*/

addr_serv.sin_addr.s_addr= htonl(INADDR_ANY); /*任意本地地址*/
/*套接字绑定*/

if(bind(sock_fd,(structsockaddr *)&addr_serv),sizeof(struct sockaddr_in)) <0)

{

perror(“bind”);

exit(1);

}

//设置服务器侦听队列的长度

if(listen(sock_fd,5) <0){

perror(“listen”);

exit(1);

}

4. accept(接收一个网络请求)

1>函数功能:

当一个客户端的连接请求到达服务器主机侦听的端口时,此时客户端的连接会在队列中等待,知道使用服务器处理接收请求。

函数accept()成功执行后,会返回一个新的套接口文件描述符来表示客户端的连接,客户端连接的信息可以通过这个新描述符来获得。因此当服务器成功处理客户端的请求连接后,会有两个文件描述符,老的文件描述符表示客户端的连接,函数send()和recv()通过新的文件描述符进行数据收发。

2>函数原型:

#include<sys/types.h>

#include<sys/socket.h>

intaccept(int sock_fd,struct sockaddr*addr,socklen_t *addrlen);

3>形参

Ø sock_fd:是由函数socket创建,经函数bind绑定到本地某一端口上,然后通过函数listen转化而来的监听套接字。

Ø addr:用来保存发起连接请求的主机的地址和端口。

Ø addrlen是addr 所指向的结构体的大小。

4>返回值:accept()函数的返回值是新连接的客户端套接字文件描述符,与客户端之间的通信是通过accept()返回的新套接字文件描述符来进行的,而不是通过建立套接字时的文件描述符。如果accept()函数发生错误,accept()会返回-1,通过errno可以得到错误值。

5>如果参数sock_fd所指定的套接字被设置为阻塞方式(Linux下的默认方式),且连接请求队列为空,则accept()将被阻塞直到有连接请求到此为止;如果参数s所指定的套接字被设置为非阻塞方式,如果队列为空,accept将立即返回-1,errno被设置为EAGAIN.

6>实例:

int client_fd;

int client_len;

struct sockaddr_in client_addr;

client_len = sizeof(struct sockaddr_in);

client_fd = accept(sock_fd,(struct sockaddr *)&client_addr,&client_len);

if(conn_fd< 0){

perror(“accept”);

exit(1);

}

5. connect(连接目标网络服务器)

1>函数功能:

客户端在建立套接字之后,不需要进行地址绑定,就可以直接连接服务器。连接服务器的函数为connect(),此函数连接指定参数的服务器,例如IP地址,端口号。

如果是TCP编程,则connect()函数用于服务器发出连接请求,服务器的IP地址和端口号由 参数serv_addr指定。

如果是UDP编程,则connect函数并不建立真正的连接,它只是告诉内核与该套接字进行通信的目的地址(由第二个参数指定),只有该目的地址发来的数据才会被该socket接收。调用connect函数的好处是不必在每次发送和接收数据时都指定目的地址。

2>函数原型:

#include<sys/types.h>

#include<sys/socket.h>

int connect(int sock_fd,struct sockaddr *serv_addr,socklen_taddrlen);

3>形参:

Ø sock_fd:建立套接字时返回的套接字文件描述符,调用socket()返回的。

Ø serv_addr:是一个指向数据结构sockaddr的指针,其中包括客户端需要连接的服务器的目的IP地址和端口号。

Ø addrlen:表示了第二了参数的大小,可以使用sizeof(struct sockaddr)

4>执行成功后返回0,有错误发生则返回-1,错误代码存入errno中。

5>实例:

int sock_fd;

struct sockaddr_in serv_addr;
if(-1 == (sock_fd == socket(AF_INET,SOCK_STREAM,0))){

printf(“Error: Unable to createsocket(%i)…\n”,errno);

perror(“sockets”);

exit(1);

}

memset(&serv_addr,0,sizeof(structsockaddr_in));

serv_addr.sin_family= AF_INET;

serv_addr.sin_port= htons(DEST_PORT);

serv_addr.sin_addr.s_addr= inet(DEST_IP_ADDRESS);

if(-1== connect(sock_fd,(struct sockaddr *)&serv_add,sizeof(struct sockaddr))){

printf(“Error:unable to the establishconnection to socket(%i)…\n”,errno);

perror(“socks”);

close(sock_fd);

exit(1);

}

6. send(发送数据)

1>函数功能:函数send用来在TCP套接字上发送数据,send只能对处于连接状态的套接字使用。

2>函数原型

#include<sys/types.h>

#include<sys/socket.h>

ssize_t send(int conn_fd,const void *msg,size_t len, int flags);

3>函数形参:

Ø conn_fd:为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符。

Ø msg:存放发送数据的缓冲区。

Ø len:发送缓冲区的长度

Ø flags:为控制选项,一般设置为0,或取以下值:

² MSG_OOB:在指定的套接字上发送带外数据(out-of-band data),该类型的套接字必须支持带外数据(如:SOCK_STREAM).

² MSG_DONTROUTE:通过最直接的路径发送数据,而忽略下层协议的路由设置。

4>返回值:

执行成功返回实际发送数据的字节数,出错则返回-1,错误代码存入errno中。

执行成功只是说明数据写入套接字的缓冲区中,并不表示数据已经成功地通过网络发送到目的地。

5>实例:

#define BUFFERSIZE1500

char send_buf[BUFFERSIZE];

……

if(send(conn_fd,send_buf,len,0)< 0){

perror(“send”);

exit(1);

}

7. recv(接收数据)

1>函数功能:recv()用来TCP套接字上接收数据。函数recv从指定的套接字描述符上接收数据并保存到指定buf中。

2>函数原型

#include<sys/types.h>

#include<sys/socket.h>

ssize_t recv(int conn_fd,void *buf,size_t len,int flags);

3>函数形参:

Ø conn_fd: 为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符

Ø buf:接收缓冲区

Ø len:接收缓冲区的大小

Ø flags:为控制选项,一般设置为0或取以下数值

² MSG_OOB:请求接收带外数据

² MSG_PEEK:只查看数据而不读出

² MSG_WAITALL:只在接收缓冲区满时才返回。

4>函数返回值

函数执行成功返回接收到的数据字节数,出错返回-1,错误代码存入errno中。

5>实例:

#define BUFFERSIZE1500

charrecv_buf[BUFFERSIZE];

……

if(recv(conn_fd,recv_buf,sizeof(recv_buf),0)< 0){

perror(“recv”);

exit(1);

}

8. close

1>函数原型:

int close(int fd);

2>函数功能:

函数close用来关闭一个套接字描述符。

3>函数形参:

Ø 参数fd为一个套接字描述符。

4>返回值:

执行成功返回0,出错则返回-1.错误代码存入errno中。

说明:close()函数的头文件是#include<unistd.h>.

三.基于Linux的TCP套接字编程实例

1.实例程序分为服务器端和客户端,客户端把Hello tigerjibo发送给服务器端;服务器端接收到字符串后,发送接收到的总字符串个数给客户端;

2.服务器端程序:



1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<errno.h>
5
6
7 #include<sys/types.h>
8 #include<sys/socket.h>
9 #include<unistd.h>//close()
10 #include<netinet/in.h>//struct sockaddr_in
11 #include<arpa/inet.h>//inet_ntoa
12 #define QUEUE_LINE 12
13 #define SOURCE_PORT 8000
14
15 #define SOURCE_IP_ADDRESS "192.168.1.6"
16
17 void process_info(int s)
18 {
19 int recv_num;
20 int send_num;
21 char recv_buf[50];
22 char send_buf[50];
23 while(1){
24 printf("begin recv:\n");
25 recv_num = recv(s,recv_buf,sizeof(recv_buf),0);
26 if(recv_num <0){
27 perror("recv");
28 exit(1);
29 } else {
30 recv_buf[recv_num] = '\0';
31 printf("recv sucessful:%s\n",recv_buf);
32 }
33 sprintf(send_buf,"recv %d numbers bytes\n",recv_num);
34 printf("begin send\n");
35 send_num = send(s,send_buf,sizeof(send_buf),0);
36 if (send_num < 0){
37 perror("sned");
38 exit(1);
39 } else {
40 printf("send sucess\n");
41 }
42 }
43 }
44 int main()
45 {
46 int sock_fd,conn_fd;
47 int client_len;
48 pid_t pid;
49 struct sockaddr_in addr_serv,addr_client;
50 sock_fd = socket(AF_INET,SOCK_STREAM,0);
51 if(sock_fd < 0){
52 perror("socket");
53 exit(1);
54 } else {
55 printf("sock sucessful\n");
56 }
57 //初始化服务器端地址
58 memset(&addr_serv,0,sizeof(addr_serv));
59 addr_serv.sin_family = AF_INET;
60 addr_serv.sin_port = htons(SOURCE_PORT);
61 addr_serv.sin_addr.s_addr =inet_addr(SOURCE_IP_ADDRESS);
62 client_len = sizeof(struct sockaddr_in);
63 if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0){
64 perror("bind");
65 exit(1);
66 } else {
67 printf("bind sucess\n");
68 }
69 if (listen(sock_fd,QUEUE_LINE) < 0){
70 perror("listen");
71 exit(1);
72 } else {
73 printf("listen sucessful\n");
74 }
75 while(1){
76 printf("begin accept:\n");
77 conn_fd = accept(sock_fd,(struct sockaddr *)&addr_client,&client_len);
78 if(conn_fd < 0){
79 perror("accept");
80 exit(1);
81 }
82 printf("accept a new client,ip:%s\n",inet_ntoa(addr_client.sin_addr));
83 pid = fork();
84 if(0 == pid){ //子进程
85 close(sock_fd);//在子进程中关闭服务器的侦听
86 process_info(conn_fd);//处理信息
87 } else {
88 close(conn_fd);//在父进程中关闭客户端的连接
89 }
90 }
91
92 }

3.客户端程序:
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<errno.h>
5
6 #include<sys/types.h>
7 #include<sys/socket.h>
8 #include<unistd.h>//close()
9 #include<netinet/in.h>//struct sockaddr_in
10 #include<arpa/inet.h>//inet_ntoa
11
12 #define DEST_PORT 8000
13 #define DEST_IP_ADDRESS "192.168.1.6"
14
15 /*客户端的处理过程*/
16 void process_info(int s)
17 {
18 int send_num;
19 int recv_num;
20 char send_buf[]="tigerjibo";
21 char recv_buf[50];
22 while(1){
23 printf("begin send\n");
24 send_num = send(s,send_buf,sizeof(send_buf),0);
25 if (send_num < 0){
26 perror("send");
27 exit(1);
28 } else {
29 printf("send sucess:%s\n",send_buf);
30 }
31 printf("begin recv:\n");
32 recv_num = recv(s,recv_buf,sizeof(recv_buf),0);
33 if(recv_num < 0){
34 perror("recv");
35 exit(1);
36 } else {
37 recv_buf[recv_num]='\0';
38 printf("recv sucess:%s\n",recv_buf);
39 }
40 }
41 }
42 int main(int argc,char *argv[])
43 {
44 int sock_fd;
45 struct sockaddr_in addr_serv;//服务器端地址
46
47 sock_fd = socket(AF_INET,SOCK_STREAM,0);
48 if(sock_fd < 0){
49 perror("sock");
50 exit(1);
51 } else {
52 printf("sock sucessful:\n");
53 }
54 memset(&addr_serv,0,sizeof(addr_serv));
55 addr_serv.sin_family = AF_INET;
56 addr_serv.sin_port = htons(DEST_PORT);
57 addr_serv.sin_addr.s_addr = inet_addr(DEST_IP_ADDRESS);
58 if( connect(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr)) < 0){
59 perror("connect");
60 printf("connect (%d)\n",errno);
61 exit(1);
62 } else {
63 printf("connect sucessful\n");
64 }
65 process_info(sock_fd);
66 close(sock_fd);
67 }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Linux下的TCP编程 的相关文章

  • 并行计算出现 pickle.PicklingError

    from multiprocessing import Pool def my function x return x x if name main inputs 1 2 3 4 5 with Pool 2 as p results p m
  • Unity面试题

    Unity基础面试题 1 什么是协同程序 2 Unity3D中碰撞器和触发器的区别 3 物体发生碰撞的必要条件 4 ArrayList和list的区别 5 如何安全的在不同工程间迁移Asset 6 OnEnable Awake Start的
  • Dubbo高级应用-服务治理

    目录 1 dubbo admin 2 7 x版本安装部署 1 1 下载源码 1 2 部署访问 2 路由规则 2 1 Dubbo API配置 2 2 管理控制台配置 3 规则动态配置 3 1 应用粒度 3 2 服务粒度 4 服务降级 5 集群
  • 集成 CUDA 实现 GPU 加速 OpenCV 计算机视觉

    特点 详细概述了将 OpenCV 与 CUDA 集成以用于实际应用 理解GPU与CUDA编程 通过一些实际示例 探索使用GPU和CUDA的OpenCV加速 熟悉在 NVIDIA Jetson TX1 上部署 OpenCV 应用程序 介绍了
  • python 类装饰器和函数装饰器区别_Python各种类型装饰器详解说明

    装饰器说明 Python中的装饰器是一种可以装饰其它对象的工具 该工具本质上是一个可调用的对象 callable 所以装饰器一般可以由函数 类来实现 装饰器本身需要接受一个被装饰的对象作为参数 该参数通常为函数 方法 类等对象 装饰器需要返

随机推荐

  • -day15--内置模块与开发规范

    day15 内置模块和开发规范 目标 掌握常见的内置模块的使用及了解软件开发的规范 今日概要 内置模块 json time datetime re 开发规范 主文件 配置文件 数据 附件 业务代码 1 内置模块 1 1 json json模
  • Win10+mingw64条件下编译和使用TBB(环境变量太神奇了!)

    Win10 mingw64 VSCode条件下编译和使用TBB Win10 mingw64条件下编译和使用TBB 编译TBB 环境变量的设置 TBB使用示例 总结与展望 Win10 mingw64条件下编译和使用TBB 本文记录在Win10
  • java中.xlsx或者.xls格式的Excel导入(servlet中处理的)

    1 第一步 在pom xml文件中添加maven依赖
  • 二、Node.js---模块化

    目录 模块化的基本概念 Node js中模块化 Node js 中模块的分类 加载模块 Node js 中的模块作用域 模块作用域 向外共享模块作用域中的成员 Node js 中的模块化规范 npm与包 在项目中安装包 包的语义化版本规范
  • 运放-滞回(迟滞)比较器全流程实战计算

    比较器之滞回 迟滞 比较器实战计算 下面我们进行一个电池低电压保护的电路设计 其中会介绍到滞回比较器的实际用法以及详细计算推导过程 假设我们定18 5V为电池欠压保护电压 也就是说在当前负载情况下电池电压低于18 5V时 其他功能会被限制住
  • linux中如何重新configure(或去除已configure的文件)

    linux中如何重新configure 或去除已configure的文件 linux中 在安装源码软件前 需要configure命令来进行安装配置 有时configure后需要重新configure 这时需要进行一些操作 已放置出错 以在f
  • 如何使用C ++以编程方式在Word文档中使用注释?

    Microsoft Word使您能够向Word文档添加注释 在诸如建议改进文档或共享文本思想等情况下 注释可能会有所帮助 在某些情况下 需要以编程方式管理评论 为此 本文将教您如何使用C 在Word文档中使用注释 让我们探索以下有关的内容
  • 12306验证码识别

    1 安装tesseract https digi bib uni mannheim de tesseract 安装时安装语言包 不过我安装了好多次都没成功 好像是被墙了 所以语言包使用https github com tesseract o
  • Linux驱动入门(1)hello驱动

    前言 1 学习韦东山老师的Linux 因为他讲的很精简 以至于很多人听不懂 接下来我讲介绍韦东山老师的驱动实验班的第一个Hello程序 2 注意 请先学习完视频再来看这个教程 本文仅供入门学习 如需深入 请搜索其他博客 3 gitee仓库
  • osgEarth的Rex引擎原理分析(七十七)rex引擎中绘制瓦片的调度过程原理

    目标 七十二 中的问题151 主要是分析瓦片什么时候进入场景树 什么时候从场景树中移出 1 初始化 osgEarthDrivers engine rex RexTerrainEngineNode cpp void RexTerrainEng
  • Git 常见错误 之 fatal: Authentication failed 简单解决方法

    Git 常见错误 之 fatal Authentication failed 简单解决方法 目录 Git 常见错误 之 fatal Authentication failed 简单解决方法 一 简单介绍 二 问题现象 三 解决方法 1 修改
  • ADS1115(ADC)16 位分辨率的高精度模数转换器的操作步骤

    ADS1113 ADS1114 和ADS1115 是具有16 位分辨率的高精度模数转换器 ADC 采用超小型的无引线QFN 10 封装或MSOP 10 封装 ADS1113 4 5 在设计时考虑到了精度 功耗和实现的简易性 ADS1113
  • Java的反射技术(Class类,Constructor类,Method类, Field类)

    Java编码时知道类和对象的具体信息 此时直接对类和对象进行操作即可 无需反射 如果编码时不知道类或者对象的具体信息 此时应该使用反射来实现 为什么要使用反射 反射就是把Java类中的各种成分映射成一个个的java对象 例如 一个类有 成员
  • 基于QT:温度串口图像显示

    用Qt自己写一个上位机 将串口发过来的温度信息 显示出来 并且绘画出温度曲线 上图 采用QT绘画曲线 首先当然是采用 qwt控件 而Qt没有自带的qwt控件 所以需要按住移植qwt控件方法具体步骤如下 1 Download and inst
  • 图表、数据可视化笔记

    框架 Echarts Three js ECharts Echarts在线例子 EChartsGallary https www makeapie com explore html sort ranktimeframe allauthor
  • 多操作系统的服务器虚拟化详解 蓝色梦想网

    虚拟化有很多种技巧 这里我们将主要解释有关在硬件上模拟运行两个或者更多操作系统的服务器虚拟化 可以说 因为虚拟化技术避免了服务器使用浪费 所以这项技术获得了广泛应用 一般来说 一台服务器装载和使用一个物理服务器操作系统 一般服务器的平均CP
  • docker应用笔记

    三个概念 Image 只读模板 可以创建docker容器 docker images 列出本地镜像 docker rmi IDXXX 移除镜像 Container 从镜像创建的运行实例 docker ps 运行中的容器 docker ps
  • 用OpenWrt软路由做旁路由-VMWARE版

    1 环境准备 OpenWrt镜像 在vmware中安装的镜像源下载地址 openwrt releases安装包下载 开源镜像站 阿里云本例使用的是22 03 2版本 下载地址https mirrors aliyun com openwrt
  • 3ds max文件打包?max插件CG Magic一键打包整起!

    3ds max文件如何打包 这个问题 小编听到不少网友的提问 今天CG Magic小编来和大家聊聊 文件更高效的操作 如何打包处理呢 3DMAX这款软件的受众群体是比较高的 在工作方便的同时 共享打包也是比较方便的 3DMAX创建的文件打包
  • 基于Linux下的TCP编程

    基于Linux的TCP网络编程 一 Linux下TCP编程框架 TCP网络编程的流程包含服务器和客户端两种模式 服务器模式创建一个服务程序 等待客户端用户的连接 接收到用户的连接请求后 根据用户的请求进行处理 客户端模式则根据目的服务器的地