linux network programming hodgepodge == linux application programming 7

Brother Dong's practice diary 2022-08-06 14:04:09 阅读数:87

linuxnetworkprogramminghodgepodgelinux

一、Linux 网络编程框架

1、网络是分层的

  • (1)OSI 七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层.
  • (2)网络为什么要分层:互联网及其复杂,需要分层以便更好地实现网络通信.

2.TCP/IP 协议引入

  • (1)TCP/IP The protocol is the most used network implementation protocol.
  • (2)TCP/IP 协议分为四层,对应着 OSI the seventh floor:应用层(包括 OSI 的表示层和会话层)、传输层、网络层、链路层(包括 OSI 的物理层).
  • (3)The application layer is most concerned with network programming,了解传输层,The network layer and link layer do not care.

3、BS 和 CS

  • (1)BS 架构:broswer-server,浏览器-服务器框架.
  • (2)CS 架构:client-server,客户端-服务器框架

二、TCP 协议的学习 1

1.关于 TCP 理解的重点

  • (1)TCP 协议工作在传输层,对上服务 socket 接口,对下调用 IP 层
  • (2)TCP 协议面向连接,Before communication, a three-way handshake must be performed to establish a connection relationship.
  • (3)TCP 协议提供可靠传输,不怕丢包、乱序等问题.

2、TCP 如何保证可靠传输

  • (1)TCP Before transmitting valid information, both parties are required to shake hands to establish a connection.
  • (2)TCP The receiver will send it after receiving the packet ack 给发送方,若发送方未收到 ack The packet is lost and retransmitted.
  • (3)TCP The valid content will be accompanied by verification information,to prevent errors in the content during transmission.
  • (4)The sender assigns a number to each message,The receiver will check the number after receiving the message,Retransmit if the sequence is wrong.
  • (5)TCP The sending rate will be adjusted according to the network conditions(滑动窗口协议)

三、TCP 协议的学习 2

1、TCP 的三次握手

  • (1)建立连接需要三次握手:客户端向服务器发送 SYN 报文,服务器回复 SYN + ACK 报文, 客户端回复 ACK 报文.The purpose of the three-way handshake is to prevent the invalid connection request segment from being suddenly transmitted to the server,产生错误.
    • ①第一次握手:客户端发送一个 TCP 标志位 SYN=1,ACK=0 的数据包给服务端,and randomly produced 生一个 Seq=J.When the server receives this data,服务端由 SYN=1 Knowing that the client is 想要建立连接.
    • ②第二次握手:The server needs to confirm the connection request of the client,Send the reply number to the client ACK=1、SYN=1 , 确认号 Ack=J+1,This value is the client's serial number plus 1,A random serial number is also generated Seq=K,This tells the client that the connection can be made.
    • ③第三次握手:The client checks after receiving the data Ack 是否为 J+1,以及标志位 ACK 的值是否为 1,若 为 1,则会发送 ACK=1、确认号码 Ack=K+1,告诉服务端,Your request connection is confirmed 认,连接可以建立,Client 和 Server 进入 ESTABLISHED 状态,完成三次握手, 随后 Client 与 Server 之间可以开始传输数据了.
  • (2)建立连接的条件:服务器 accept 时客户端主动发起 connect.

2、TCP 的四次挥手

  • (1)关闭连接需要四次挥手:客户端向服务器发送FIN报文,服务器回复ACK报文;服务器向客户端发送FIN+ACK报文,客户端回复ACK报文.(Client and server are interchangeable)
  • (2)Both the client and the server can initiate a shutdown actively.
  • 注:这些握手协议已经封装在 TCP 协议内部,socket 编程接口平时不用管

3、基于 TCP 通信的服务模式

  • (1)具有公网 IP 地址的服务器(或者使用动态 IP 地址映射技术).
  • (2)服务器端 socket、bind、listen、accept 后处于监听状态.
  • (3)客户端 socket 后,直接 connect 去发起连接.
  • (4)After the server receives the application and agrees to the client's access, it will be established TCP 连接,然后双方开始收发数据.
  • (5)双方均可发起关闭连接.

4、common use TCP 协议的网络应用

  • (1)http、ftp
  • (2)QQ 服务器
  • (3)mail 服务器

四、socket 编程接口介绍

在这里插入图片描述
1、建立连接

  • (1)socket 函数:建立一个套接口,类似于 open,用来打开一个网络连接,如果成功则返 回一个网络文件描述符(int),之后我们操作这个网络连接都通过这个网络文件描述符.
  • (2)bind 函数:将 socket 建立的套接口与一个本地地址捆绑(主机地址/端口号).
  • (3)listen 函数:把一个未连接的套接字转换成一个被动套接字,指示内核应该接受指向该 套接字的连接请求.
  • (4)accept 函数:开始接收从客户端发来的请求信息.
  • (5)connect 函数:发起对服务器的连接请求,三次握手在此时开始.

2、发送和接收

  • (1)send 和 write:都是用来发送信息.
  • (2)recv 和 read:都是用来接收信息.

3、辅助性函数

  • (1) inet_aton(将字符串转换成网络地址)、inet_addr(构建网络地址)、inet_ntoa(将网络地址转换成字符串).
  • (2)inet_ntop(将网络地址转换成字符串)、inet_pton(将字符串转换成网络地址).两者都兼容 IPv4 和 IPv6.

4、表示 IP 地址相关数据结构

  • (1)都定义在 netinet/in.h.
  • (2)truct sockaddr:This structure is used in network programming to represent a IP 地址的,注意这个 IP 地址 是 兼 容 IPv4 和 IPv6 的 , 在 实 际 编 程 中 这 个 结 构 体 会 被 struct sockaddr_in 或者 struct sockaddr_in6.
  • (3)typedef uint32_t in_addr_t:网络内部用来表示 IP 地址的类型.
struct sockaddr_in{

short int sin_family;//地址族.一般来说是AF_INET和PF_INET
unsigned short int sin_port;//端口号(使用网络字节顺序).在linux下,端口号的范围是0~65535,0~1024A range of port numbers already used or reserved by the system
struct in_addr sin_addr;//存储IP地址,使用in_addr这个数据结构.
unsigned char sin_zero[8];//未来将sockaddr_in结构与sockaddr结构对齐
};
typedef uint32_t in_addr_t;
struct in_addr{

in_addr_t s_addr;
};

五、IP Address conversion function practice

1、inet_addr、inet_ntop、inet_pton:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IPADDR "192.168.1.103"
//0x66 01 a8 c0
//103 1 168 192
//网络字节序,In fact, it is the big endian mode,低字节在高地址
int main(void)
{

//使用inet_addr函数
in_addr_t addr=0;
addr=inet_addr(IPADDR);//构建网络地址
printf("addr=0x%x.\n",addr);//0x6601a8c0
return 0;
/* //使用 inet_ntop 函数 struct in_addr addr={0}; char buf[50]={0}; addr.s_addr=0x6703a8c0; inet_ntop(AF_INET,&addr,buf,sizeof(buf));//将网络地址转换成字符串 printf("ip addr = %s.\n", buf); //使用 inet_pton 函数 int ret=0; struct in_addr addr={0}; ret=inet_pton(AF_INET,IPADDR,&addr);//将字符串转换成网络地址 if(ret!=1) return -1; printf("addr=0x%x.\n",addr.s_addr); */
}

六、socket 编程实践 1

1、服务器端程序编写

  • (1)socket. (sockfd)Create socket pseudo-file
  • (2)bind. Bind to the socketport和ip(本身)
  • (3)listen.How many clients are allowed to connect to me at the same time
  • (4)accept:返回值是一个 fd(chilfd),accept A correct return indicates that it has been established with the client TCP 连接,之后需 corresponding to this connection fd to read and write with the client.
  • 注意:socket 返回的 fd called monitoring fd,是用来监听客户端的,不能读写;accept 返回的 fd call even 接 fd,用来读写.
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERPORT 9003
#define SERADDR "127.0.0.1"//本地地址
#define BACKLOG 100
int main(void)
{

int sockfd=-1,ret=-1,chilfd=-1;
socklen_t len=0;
struct sockaddr_in seraddr={
0};
struct sockaddr_in cliaddr={
0};
//第一步:先socket建立一个套接口,得到监听sockfd
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd){

perror(socket);exit(-1);
}
printf("socketfd = %d.\n", sockfd);
//第二步:bind绑定sockfd和当前电脑的ip地址&端口号
seraddr.sin_family=AF_INET;//设置地址族为IPV4
seraddr.sin_port=htons(SERPORT);//设置地址的端口号信息
seraddr.sin_addr.s_addr=inet_addr(SERADDR);//设置IP地址
ret=bind(sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0) return -1;
printf("bind success.\n");
//第三步:listen监听端口
ret=listen(sockfd,BACKLOG);//阻塞等待客户端来连接服务器
if(ret<0){

perror("listen");exit(-1);
}
printf("listen success.\n");
//第四步:accept阻塞等待客户端接入
clifd=accept(sockfd,(struct sockaddr*)&cliaddr,&len);
printf("连接已经建立,client fd=%d.\n",clifd);
return 0;
}

2、客户端程序的编写

  • (1)socket.
  • (2)connect.connect和bind参数一致,The former is the address of the other party and the latter is its own address
  • 概念:端口号,实质就是一个数字编号,Used to uniquely identify a process that can access the Internet in the operating system of a host.Every data packet transmitted on the network contains the sender and receiver IP 地址和端口号.
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERADDR "127.0.0.1"//服务器开放给我们的IP地址和端口号 
#define SERPORT 9003
int main(void)
{

int sockfd=-1,ret=-1;
struct sockaddr_in seraddr={
0};
//第一步:先socket建立一个套接口
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd){

perror("socket");return -1;
}
printf("socketfd=%d.\n",sockfd);
//第二步:connect连接服务器
seraddr.sin_family=AF_INET;//IPV4
seraddr.sin_port=htons(SERPORT);//端口号
seraddr.sin_addr.s_addr=inet_addr(SERADDR);//设置IP地址
ret=connect(sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){

perror("listen");exit(-1);
}
printf("connect successfully.\n");
return 0;
}

七、socket 编程实践 2

1、客户端发送&服务器接收

//The client sends repeatedly
while(1){

pritnf("Enter the content to send\n");
scanf("s%",sendbuf);
ret=send(sockfd,sendbuf,strlen(sendbuf),0);
printf("发送了%d个字符\n",ret);
}
//The server receives it repeatedly
while(1){

ret=recv(clifd,recvbuf,sizeof(recvbuf),0);
printf("clientThe content sent is:%s.\n",recvbuf);
memset(recvbuf,0,sizeof(recvbuf));
}

2、服务器发送&客户端接收

//服务器给客户端发
strcpy(sendbuf,"hello world.");
ret=send(clifd,sendbuf,strlen(sendbuf),0);
printf("发送了%d个字符\n",ret);
//客户端接收
ret=recv(sockfd,recvbuf,sizeof(recvbuf),0);
printf("serverThe content sent is:%s\n",recvbuf);

3、探讨:How to make the client and server communicate well

  • (1)In principle, both the client and the server can send and receive arbitrarily,But in fact the two sides have to cooperate
  • (2)必须了解到的一点:client 和 server 之间的通信是异步的,这就是问题的根源.
  • (3)解决方案:依靠应用层协议来解决,就是 server 和 client Make a series of communication agreements in advance.

八、socket 编程实践 3==important

1、自定义应用层协议第一步:规定发送和接收方法.

  • (1)It is stipulated that after the connection is established, the client actively sends a request packet to the server,The server replies with one after receiving it 应答数据包,这就是一个通信回合.
  • (2)整个连接的通信就是由 N 多个回合组成的.
//=======client.c文件
while(1){

//The first step in the round:客户端给服务器发送信息
printf("请输入要发送的内容");
scanf("%s",sendbuf);
ret=send(sockfd,sendbuf,strlen(sendbuf),0);
printf("向server发送了%d个字符.\n",ret);
//Second step in the round:The client receives the reply from the server
memset(recvbuf,0,sizeof(recvbuf));
ret=recv(sockfd,recvbuf,sizeof(recvbuf),0);
printf("serverThe content sent is:%s\n",recvbuf);
//The third step in the round:The client parses the server's reply,Make the next decision
}
//=======server.c文件
while(1){

//Round middle1步:服务器接收客户端消息
memset(recvbuf,0,sizeof(recvbuf));
ret=recv(clifd,recvbuf,sizeof(recvbuf),0);
printf("clientThe content sent is:%s\n",recvbuf);
//Second step in the round:服务器回复客户端消息
printf("请输入要发送的内容\n");
scanf("%s",sendbuf);
ret=send(clifd,sendbuf,strlen(sendbuf),0);
printf("向 client 发送了%d 个字符\n", ret);
// Round middle 3 步:The server parses the client's reply,Make the next decision
}

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

//=======client.c文件
#define CMD_REGISTER 1001 // 注册学生信息 
#define CMD_CHECK 1002 // Check student information 
#define CMD_GETINFO 1003 // 获取学生信息 
#define STAT_OK 30 // 回复 ok 
#define STAT_ERR 31 // Reply wrong
typedef struct commu
{

char name[20];//学生姓名
int age;// 学生年龄
int cmd;// 命令码
int stat;//状态信息,用来回复
}info;
while(1){

//The first step in the round:客户端给服务器发送信息
info st1;
printf("请输入学生姓名\n");
scanf("%s",&st1.name);
printf("请输入学生年龄");
scanf("%d",&st1.age);
st1.cmd=CMD_REGISTER;
ret=send(sockfd,&st1,sizeof(st1),0);
printf("发送了 1 个学生信息\n");
//Second step in the round:客户端接收服务器信息
memset(&st1,0,sizeof(st1));
ret=recv(sockfd,&st1,sizeof(st1),0);
//The third step in the round:The client parses the server's reply,Make the next decision
if(st1.stat==STAT_OK)
printf("注册学生信息成功\n");
else
printf("Failed to register student information\n");
}
//=======server.c文件
#define CMD_REGISTER 1001 // 注册学生信息 
#define CMD_CHECK 1002 // Check student information 
#define CMD_GETINFO 1003 // 获取学生信息 
#define STAT_OK 30 // 回复 ok 
#define STAT_ERR 31 // Reply wrong
typedef struct commu
{

char name[20];//学生姓名
int age;// 学生年龄
int cmd;// 命令码
int stat;//状态信息,用来回复
}info;
while1(1){

info st;
//Round one:服务器接收客户端信息
memset(recvbuf,0,sizeof(recvbuf));
ret=recv(clifd,&st,sizeof(st),0)
printf("clientThe content sent is:%s\n",recvbuf);
//Round two:The server parses the client packet,然后干活
if(st.cmd==CMD_REGISTER){

printf("User wants to register student information.\n");
printf("学生姓名:%s,学生年龄:%d.\n",st.name,st.age);
/*Here the server needs to perform the real registration action,Generally, a piece of information is inserted into the database ************************************* *************************************/
//The third step of the round:The server sends the client,回复
st.stat=STAT_OK;
ret = send(clifd, &st, sizeof(info), 0);
printf("注册完成\n");
}
if (st.cmd == CMD_CHECK) {
}
if (st.cmd == CMD_GETINFO) {
}
}

3、常用应用层协议:http、ftp……

九、TCP与UDP

1 、TCP、UDP的区别

  • TCP—传输控制协议,提供的是面向连接、可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.
  • UDP—用户数据报协议,是一个简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地.
  • 区别:
    • 1)TCP是面向连接的,UDP是面向无连接的
    • 2)UDP程序结构较简单
    • 3)TCP是面向字节流的,UDP是基于数据包的
    • 4)TCP保证数据正确性,UDP可能丢包
    • 5)TCP保证数据顺序到达,UDP不保证

2 、TCP、UDP的优缺点

  • TCP优点:可靠稳定.TCP的可靠体现在TCP在传输数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完之后,还会断开来连接用来节约系统资源.TCP缺点:慢,效率低,占用系统资源高,易被攻击在传递数据之前要先建立连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞机制等都会消耗大量时间,而且要在每台设备上维护所有的传输连接.然而,每个连接都会占用系统的CPU,内存等硬件资源.因为TCP有确认机制、三次握手机制,这些也导致TCP容易被利用,实现DOS、DDOS、CC等攻击.
  • UDP优点:快,比TCP稍安全UDP没有TCP拥有的各种机制,是一种无状态的传输协议,所以传输数据非常快,没有TCP的这些机制,被攻击利用的机会就少一些,但是也无法避免被攻击
  • UDP缺点:不可靠,不稳定因为没有TCP的这些机制,UDP在传输数据时,如果网络质量不好,就会很容易丢包,造成数据的缺失.

3、TCP UDP适用场景

  • TCP:传输一些对信号完整性,信号质量有要求的信息.
  • UDP:对网络通讯质量要求不高时,要求网络通讯速度要快的场景.

4、 TCP为什么是可靠连接?

  • 因为tcp传输的数据满足3大条件,不丢失,不重复,按顺序到达.

5、OSI典型网络模型,简单说说有哪些
在这里插入图片描述

  • ICMP协议是一个网络层协议.
    一个新搭建好的网络,往往需要先进行一个简单的测试,来验证网络是否畅通;但是IP协议并不提供可靠传输.如果丢包了,IP协议并不能通知传输层是否丢包以及丢包的原因.所以我们就需要一种协议来完成这样的功能–ICMP协议.
  • ARP:地址解析协议(Address Resolution Protocol)
    • 基本功能:知道目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行.
    • 它是IPv4中网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代RARP:是将MAC物理地址转换成IP地址.
copyright:author[Brother Dong's practice diary],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/218/202208061356108643.html