网络编程
lwj~
这个作者很懒,什么都没留下…
展开
-
socket编程总结
server.c和client.c通信问题1:如果client发送空内容,server会一直接受 进入阻塞状态。可以用多进程解决。问题2:端口占用问题?可以调用setsockop,把close时间设置为0,把linger时间延长原创 2020-11-24 17:09:09 · 111 阅读 · 0 评论 -
自制HTTP服务器
在开始编写高性能 HTTP 服务器之前,先要构建一个支持 TCP 的高性能网络编程框架设计需求这个 TCP 高性能网络框架需要满足的需求有以下三点。采用reactor模型,可以灵活使用poll/epoll作为事件分发实现必须支持多线程,从而可以支持单线程单reactor模型,可以支持多线程主-从reactor模式,可以将套接字上的I/O事件分离到多个线程上封装读写操作到Buffer对象...原创 2020-01-01 15:34:17 · 1138 阅读 · 0 评论 -
异步I/O
阻塞 / 非阻塞 VS 同步 / 异步阻塞I/O第一种是阻塞 I/O。阻塞 I/O 发起的 read 请求,线程会被挂起,一直等到内核数据准备好,并把数据从内核区域拷贝到应用程序的缓冲区中,当拷贝过程完成,read 请求调用才返回。接下来,应用程序就可以对缓冲区的数据进行数据解析。非阻塞I/O非阻塞的 read 请求在数据未准备好的情况下立即返回,应用程序可以不断轮询内核,直到数据准备好...原创 2019-12-31 13:56:30 · 437 阅读 · 0 评论 -
epoll、多线程模型
如何切换epollevent_loop.c 文件的 event_loop_init_with_name 函数是关键,通过宏 EPOLL_ENABLE 来决定是使用 epoll 还是 poll 的。struct event_loop *event_loop_init_with_name(char *thread_name) { ...#ifdef EPOLL_ENABLE yol...原创 2019-12-29 12:35:01 · 1009 阅读 · 0 评论 -
子线程使用poll处理连接I/O事件
在发起连接请求的客户端非常多的情况下,单 reactor 线程既分发连接建立,又分发已建立连接的 I/O,有点忙不过来,在实战中的表现可能就是客户端连接成功率偏低。可以将 acceptor 上的连接建立事件和已建立连接的 I/O 事件分离,形成所谓的主 - 从 reactor 模式。主 - 从reactor模式核心思想:主反应堆线程只负责分发Acceptor连接建立,已连接套接字上的I/O事...原创 2019-12-28 16:08:36 · 453 阅读 · 0 评论 -
使用poll单线程处理I/O事件
通过使用 poll、epoll 等 I/O 分发技术,可以设计出基于套接字的事件驱动程序,从而满足高性能、高并发的需求。事件驱动模型,也被叫做反应堆模型(reactor),或者是 Event loop 模型。这个模型的核心有两点。它存在一个无限循环的事件分发线程,或者叫做 reactor 线程、Event loop 线程。这个事件分发线程的背后,就是 poll、epoll 等 I/O 分发技术...原创 2019-12-28 10:33:23 · 681 阅读 · 0 评论 -
阻塞I/O和线程模型
进程切换上下文的代价是比较高的,所以线程是比较轻量级的模型线程(thread)是运行在进程中的一个“逻辑流”,现代操作系统都允许在单进程中运行多个线程。线程由操作系统内核管理。每个线程都有自己的上下文(context),包括一个可以唯一标识线程的 ID(thread ID,或者叫 tid)、栈、程序计数器、寄存器等。在同一个进程中,所有的线程共享该进程的整个虚拟地址空间,包括代码、数据、堆、共享...原创 2019-12-24 21:22:29 · 145 阅读 · 0 评论 -
阻塞I/O和进程模型
父进程和子进程fork 函数实现的时候,实际上会把当前父进程的所有相关值都克隆一份,包括地址空间、打开的文件描述符、程序计数器等,就连执行代码也会拷贝一份,新派生的进程的表现行为和父进程近乎一样,就好像是派生进程调用过 fork 函数一样。为了区别两个不同的进程,实现者可以通过改变 fork 函数的栈空间值来判断,对应到程序中就是返回值的不同。if (fork() == 0) { do_ch...原创 2019-12-24 15:11:24 · 216 阅读 · 0 评论 -
C10K,高并发设计模型
C10K 问题:如何在一台物理机上同时服务 10000 个用户?这里 C 表示并发,10K 等于 10000。操作系统层面文件句柄每个客户端连接都代表一个文件描述符,一旦文件描述符不够用了,新的连接就会被放弃,报错:Socket/File:Can't open so many files在 Linux 下,单个进程打开的文件句柄数是有限制的,没有经过修改的值一般都是 1024。$ul...原创 2019-12-21 20:56:40 · 334 阅读 · 0 评论 -
epoll
本质上 epoll 还是一种 I/O 多路复用技术, epoll 通过监控注册的多个描述字,来进行 I/O 事件的分发处理。不同于 poll 的是,epoll 不仅提供了默认的 level-triggered(条件触发)机制,还提供了性能更为强劲的 edge-triggered(边缘触发)机制。epoll使用epoll_createepoll_create() 方法创建了一个 epoll 实...原创 2019-12-21 11:07:23 · 101 阅读 · 0 评论 -
非阻塞I/O
非阻塞 I/O 配合 I/O 多路复用,是高性能网络编程中的常见技术。阻塞 VS 非阻塞阻塞I/O完成某个操作时,应用程序会被挂起,等内核完成操作。内核将CPU时间切换给其他有需要的进程,网络应用程序此时得不到CPU时间。比方说书店买书,告诉老板(内核)想要的书,然后你一直等着,老板就会去找,可能会去全城其他书店找。此时就好像书店老板在这里”阻塞“了。非阻塞I/O,当应用程序完成某个...原创 2019-12-20 21:31:39 · 353 阅读 · 0 评论 -
poll,I/O多路复用
select的I/O 多路复用技术,通过描述符集合来表示检测的 I/O 对象,通过三个不同的描述符集合来描述 I/O 事件 :可读、可写和异常。缺点是:所支持的文件描述符个数有限,linux系统,select默认最大值为1024。poll函数介绍普遍使用的 I/O 多路复用技术,和select 相比,它和内核交互的数据结构有所变化,另外,也突破了文件描述符的个数限制。int poll(str...原创 2019-12-19 11:02:57 · 170 阅读 · 0 评论 -
select,I/O复用
使用fgets方法等待标准输入,没发在套接字有数据时读出数据,可以使用read方法等待套接字有数据返回,但这样做没法在标准输入有数据情况下,读入数据并发给对方。I/O 多路复用可以解决上面场景。把标准输入、套接字都看作I/O的一路,多路复用的意思,就是在任何一路有“事件”发生的情况下,通知应用程序去处理相应的I/O。使用 I/O 复用以后,如果标准输入有数据,立即从标准输入读入数据,通过套接字...原创 2019-12-18 16:33:21 · 272 阅读 · 0 评论 -
四次挥手问题
接收端接到FIN包执行被动关闭,FIN包由TCP协议栈,为FIN包插入到文件结束符EOF缓冲区,应用程序通过read调用感应FIN包。FIN包被放到已排队等候的其他已接受的数据之后,这表示EOF之后再无额外的数据到达,此时被动关闭方进入CLOSE_WAIT状态。被动关闭方读到EOF,应用程序调用close关闭它的套接字,导致它的TCP也会发送一个FIN包,被动关闭进入LAST_ACK状态主...原创 2019-12-16 17:11:14 · 252 阅读 · 0 评论 -
TCP并不总是“可靠”的?
TCP 是可靠的?发送端通过调用send函数之后,数据会先存储到套接字的发送缓冲区中,通过网络协议栈决定合适发送、如何发送。当对应的数据发送给接收端,接收端回应ACK,这时存储到发送缓冲区的数据可以删除了,但发送端无法获取对应数据流的ACK情况(无法判断对端接收到数据流),如果想知道,必须在应用层添加处理逻辑,例如显示的报文确认机制。从接收端来看,也不能保证ACK过的数据被应用程序处理,因为数...原创 2019-12-13 22:29:58 · 341 阅读 · 0 评论 -
TCP 数据”流“
在发送端,当我们调用 send 函数完成数据“发送”以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中,至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能假设每次 send 调用发送的数据,都会作为一个整体完整地被发送出去。假设发送端陆续调用 send 函数先后发送 network 和 program 报文,那么实际...原创 2019-12-12 17:37:50 · 372 阅读 · 0 评论 -
SO_REUSEADDR 套接字,解决(Address already in ues)问题
当服务器端程序重启之后,总是碰到“Address in use”的报错信息,服务器程序不能很快地重启。如果客户端发给发送服务端,原创 2019-12-12 12:10:13 · 926 阅读 · 1 评论 -
UDP也可以是“已连接”(connect),提升性能
UDP 等于无连接协议UDP connect 的作用不调用 connect 操作的客户端程序,在服务器端不开启的情况下,客户端程序是不会报错的,程序只会阻塞在 recvfrom 上,等待返回(或者超时)。通过对 UDP 套接字进行 connect 操作,将 UDP 套接字建立了”上下文“,该套接字和服务器端的地址和端口产生了联系,正是这种绑定关系给了操作系统内核必要的信息,能够将操作系统内核...原创 2019-12-11 21:26:31 · 423 阅读 · 0 评论 -
TCP协议中的动态数据传输
发送窗口、接收窗口、拥塞窗口调用数据发送接口以后……调用这些接口并不意味着数据被真正发送到网络上,其实,这些数据只是从应用程序中被拷贝到了系统内核的套接字缓冲区中,或者说是发送缓冲区中,等待协议栈的处理。流量控制和生产者 - 消费者模型作为 TCP 发送端,也就是生产者,不能忽略 TCP 的接收端,也就是消费者的实际状况,不管不顾地把数据包都传送过来。如果都传送过来,消费者来不及消费,必然...原创 2019-12-10 20:20:43 · 585 阅读 · 0 评论 -
心跳
保持对连接有效性的检测TCP Keep-Alive 选项TCP 保持活跃的机制原理TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡。上述的可定义变量,分别被称为保活时间、保活时间间隔和保活探测次数。在 Linux 系统中,这些变量分别对应 sysctl 变量net.ipv4.tcp_kee...原创 2019-12-10 14:57:52 · 232 阅读 · 0 评论 -
TCP 的四次挥手,连接关闭的2种方式(close和shutdown)
客户端主动发起连接的中断,将自己到服务器端的数据流方向关闭,此时,客户端不再往服务器端写入数据,服务器端读完客户端数据后就不会再有新的报文到达。但这并不意味着,TCP 连接已经完全关闭,服务器端可能正在对客户端的最后报文进行处理,比如去访问数据库,存入一些数据;或者是计算出某个客户端需要的值,当完成这些操作之后,服务器端把结果通过套接字写给客户端,我们说这个套接字的状态此时是“半关闭”的。最后,服...原创 2019-12-08 12:31:24 · 4632 阅读 · 2 评论 -
网络编程——TIME_WAIT
我们这个应用服务需要通过发起 TCP 连接对外提供服务。每个连接会占用一个本地端口,当在高并发的情况下,TIME_WAIT 状态的连接过多,多到把本机可用的端口耗尽,应用服务对外表现的症状,就是不能正常工作了。当过了一段时间之后,处于 TIME_WAIT 的连接被系统回收并关闭后,释放出本地端口可供使用,应用服务对外表现为,可以正常工作。这样周而复始,便会出现了一会儿不可以,过一两分钟又可以正常...原创 2019-12-05 19:57:07 · 171 阅读 · 0 评论 -
UDP方面的编程知识
TCP 是一个面向连接的协议,TCP 在 IP 报文的基础上,增加了诸如重传、确认、有序传输、拥塞控制等能力,通信的双方是在一个确定的上下文中工作的。UDP 没有这样一个确定的上下文,它是一个不可靠的通信协议,没有重传和确认,没有有序控制,也没有拥塞控制。我们可以简单地理解为,在 IP 报文的基础上,UDP 增加的能力有限。UDP 编程服务器端创建 UDP 套接字之后,绑定到本地端口,调用...原创 2019-11-24 13:12:18 · 139 阅读 · 0 评论 -
5、使用套接字进行读写
发送数据write、send 和 sendmsg。ssize_t write (int socketfd, const void *buffer, size_t size)ssize_t send (int socketfd, const void *buffer, size_t size, int flags)ssize_t sendmsg(int sockfd, const struc...原创 2019-11-22 19:54:25 · 437 阅读 · 0 评论 -
TCP三次握手,使用套接字式建立连接
服务端准备连接的过程创建套接字int socket(int domain, int type, int protocol)domain 就是指 PF_INET、PF_INET6 以及 PF_LOCAL 等,表示什么样的套接字type 可用的值是:SOCK_STREAM: 表示的是字节流,对应 TCP;SOCK_DGRAM: 表示的是数据报,对应 UDP;SOCK_RAW: 表示...原创 2019-11-20 22:50:28 · 564 阅读 · 0 评论 -
客户端-服务端网络编程模型
客户端-服务端网络编程模型还有一点需要强调的是,无论是客户端,还是服务器端,它们运行的单位都是进程(process),而不是机器IP 和端口:IP 用来表示网络世界的地址。端口比方是每间房间的号码,客户端的端口是由操作系统内核临时分配的,称为临时端口,服务器端的端口通常是一个众所周知的端口。端口号是一个 16 位的整数,最多为 65536保留网段:仅仅保留做内部使用,称作保留网段。子网...原创 2019-11-18 21:25:33 · 292 阅读 · 0 评论 -
套接字和地址
在客户端 发起连接之前,服务器端先进行初始化首先初始化socket执行bind函数,将自己服务能力绑定在一个总所周知的地址和端口上然后执行lisen,将原先的socke转化成服务器端的socket,服务器最后阻塞在accept上等待客- 户端请求的到来此时服务端准备就绪,客户端需要先进行初始化socket再进行connect向服务端的地址和端口发起连接请求,这就是著名的TCP三次握...原创 2019-11-18 21:25:20 · 538 阅读 · 0 评论 -
异步通知I/O模型和重叠I/O模型
理解异步通知I/O模型select函数,实现并发服务器端的方法之一理解同步和异步异步指“不一致”,他在数据I/O中非常有用。send&recv函数可以进行同步I/O,调用send函数,完成数据传输后才能从函数返回...原创 2019-11-02 13:18:02 · 686 阅读 · 0 评论 -
windows中的线程同步
1.用户模式和内核模式windows操作系统的运行方式是“双模式操作”用户模式:运行应用程序的基本模式,禁止访问物理设备,限制访问内存区域内核模式:操作系统运行时的模式,不会限制访问内存区域和硬件设备定义这2种模式问了提高安全性,线程这种伴随内核对象创建的资源创建过程的转换过程:用户模式–>内核模式–>用户模式从用户模式切换到内核模式为了创建资源,从内核模式再次切换到...原创 2019-10-30 15:39:55 · 356 阅读 · 0 评论