- connect : 第一次握手信息
- 第二次,第三次都是被动处理,无需调用接口
- accept不参与三次握手,取出三次握手成功的描述符
属于linux
系统描述符fd
的一部分:
f d ∈ [ 0 , 1 , 2 … … ] fd\in[0,1,2……] fd∈[0,1,2……]
总之 f d > = 0 fd>=0 fd>=0
把socket状态从主动发送状态转变为被动监听状态listen + TCP的描述符
send(sockfd, buf, 5, 0)
表示的是向文件描述符为sockfd
的目的地址发送以buf
为首地址,5个字节的内容
unsigned short 16bit [0 , 65535]
大端模式,小端模式条件 大端:0x12345678 低位地址 0x12 小端:0x12345678 低位地址 0x78
int空间的传递网络序 :大端 CPU序 :大/小端
htonl()
–“Host to Network Long” 将一个无符号长整型数值转换为网络字节序ntohl()
–“Network to Host Long” 将一个网络字节序转换为无符号长整型数值htons()
–“Host to Network Short” 将一个无符号短整型数值转换为网络字节序ntohs()
–“Network to Host Short” 将一个网络字节序转换为无符号短整型数值
socket
、bind
、send
、recv
connect
客户端
listen
、accept
服务器
- 2xx : 成功
- 3xx : 特殊功能 302 重定向
- 4xx : 客户端请求错误,服务器拒绝服务 404 not found
- 5xx : 服务器服务异常
请求报文 = 请求行+请求头+请求数据
HTTP的9个请求动作 HTTP1.0:GET
:请求指定页面的信息,并返回实体主体POST
:向指定资源提交数据进行处理请求,数据存在请求体HEAD
: 类似get,但不返回具体内容,用于获取报头
PUT
:完整替换更新指定资源数据,没有就新增DELETE
:删除指定资源的数据PATCH
:部分更新指定资源的数据OPTIONS
:允许客户端查看服务器的支持的http请求方法CONNECT
:预留给能将连接改为管道的代理服务器TRACE
:追踪服务器收到的请求,用于测试或诊断
netstat
大概这样:
接收到新连接后,单独开辟一个子进程独立处理这个新连接,也就是accept
之后
socket
bind
sendto
recvfrom
通过gethostbyname
函数即可解析
函数原型:
struct hostent *gethostbyname(const char *hostname);
通过输入域名我们可以将其解析,然后返回一个hostent
的封装数据,这个数据的结构如下:
struct hostent{
char *h_name; //official name
char **h_aliases; //alias list
int h_addrtype; //host address type
int h_length; //address lenght
char **h_addr_list; //address list
}
这样我们就能解析域名并得到真正的IP地址
TCP/IP通信 全双工全双工通过一个socket文件描述符允许数据从两边同时发送和接收
这边总结一下其他的知识点:
单工单工指的是数据只能从一方传输,并不能实现双方通信
例如:电视、广播、收音机等
半双工半双工指的是数据能从两方传输,但是同一时间数据只能在一个方向传输
例如:对讲机
全双工全双工指的是数据可以从两个方向同时传输
例如:电话
零散知识点socket
不仅仅支持TCP/IP协议和本地进程间通信- 如果系统TCP使用了80端口,那么UDP也可以使用80端口
- TCP在释放链接过程中会有四次挥手的过程
- HTTP协议是应用层协议,他传输层是基于TCP协议的
- 如果服务器不调用
accept
函数,那么三次握手不会失效 - 如果两台电脑能
ping
通,说明两台电脑的网络层是相通的。 epoll
性能比select
性能各有所长- UDP编程中,需要指定对方的IP和端口号也能通信。
sendto
可以send
可以(connect后) - CPU有小端模式,也有大端模式,处理数据
Ctrl+C
组合键实际触发的信号是SIGINT
- 在HTTP1.1规范中,
OPTIONS
动作代表允许客户端查看服务器的性能 - 在
sockaddr_in
结构体中,sin_addr
中一般使用INADDR_ANY
宏代表可以接收任意本地设备的网络数据 inet_aton
函数可以将主机字节序结构的IP地址转换为网络字节序- 在select结构中,
FD_ISSET()
宏用来判断文件描述符是否在文件集合中
通过epoll
多路复用实现高并发服务器
-
epoll
没有最大并发连接限制,上限是最大可打开文件的数目,一般这个数目和系统内存有关,但是考虑到服务器的内存一般不小,所以可以实现高并发 -
效率有明显提升,
epoll
对于句柄事件的选择和select
、poll
的遍历不同,epoll
是事件相应的,即:句柄事件来到后,立即选择出来,复杂度为常数级别 O ( 1 ) O(1) O(1),不需要遍历,内核将句柄通过红黑树保存,所以随着句柄数目的增多,IO的效率也不会随之线性下降(只是会稍微下降一点) -
内存拷贝,
select
让内核把 FD 消息通知给用户空间的时候使用了内存拷贝的方式,开销较大,但是epoll
在这点上使用了共享内存的方式,这个内存拷贝也省略了。
epoll
的设计和实现与select完全不同。epoll
通过在Linux内核中申请一个简易的文件系统,把原先的select/poll调用分成了3个部分:
- step1:
调用epoll_create()
建立一个epoll
对象(在epoll
文件系统中为这个句柄对象分配资源)
- step2:
调用epoll_ctl
向epoll
对象中添加这上万个连接的套接字
- step3:
调用epoll_wait
收集发生的事件的连接
只需要在进程启动时建立一个epoll
对象,然后在需要的时候向这个epoll
对象中添加或者删除连接。同时,epoll_wait
的效率也非常高,因为调用epoll_wait
时,并没有直接向操作系统复制这数万个连接的句柄数据,内核也不需要去遍历全部的连接。所以可以应对高并发的情况
用一个图来表明epoll处理的逻辑关系:
- 创建
socket
- 填充自己信息,公布端口
struct sockaddr_in self
、bind
- 改变为监听状态
listen
eg:
int init_listen(){//初始化监听描述符
int listen_fd;
int ret;
struct sockaddr_in server_addr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?