当前位置:网站首页>Implementation of Muduo accept connection, disconnection and sending data
Implementation of Muduo accept connection, disconnection and sending data
2022-07-03 13:49:00 【yolo_ yyh】
Catalog
One 、TcpServer Accept new connection
3、 ... and 、TcpConnection send data
Four 、 How to limit the maximum number of concurrent connections to the server
5、 ... and 、 How to kick off idle connections
6、 ... and 、 Flow control when sending data
muduo It's for Chen Shuo's personal use C++ Developed a network library , The code is of great learning value , The summary comes from books 《Linux Multithreaded server-side programming 》, Also written by Chen Shuo , Can cooperate with github Use code together .
muduo github website :https://github.com/chenshuo/muduo
One 、TcpServer Accept new connection
1、TcpServer
TcpServer The sequence of function calls related to the new connection is shown in the following figure

Channel::handleEvent() The trigger condition is listening socket Can be read , Indicates that a new connection has arrived ,TcpServer The corresponding... Will be created for the new connection TcpConnection object . When a new connection arrives ,Acceptor Callbacks newConnection(), The latter creates TcpConnection object conn, Add it to connectionMap, Set it up callback, Call again conn->connectEstablished(), Which will call the user provided ConnectionCallback.
2、TcpConnection
yes muduo The core and most complex class ,TcpConnection Use Channel get socket Upper IO event , It will take care of itself writable event , But the readable The event passed MessageCallback Send to user ,TcpConnection Have Tcp socket, The destructor will close(fd).
Two 、TcpConnection disconnect
muduo Passive shutdown is available , That is, the other party closes the connection first , Local read() return 0, Trigger shutdown logic . You can also call TcpConnection Of forceClose() Member functions , For actively closing the connection , The latter will call handleClose() function , The process of function call is shown in the following figure :

TcpServer Will send to TcpConnection register CloseCallback, Used to receive the message of disconnection .handleClose() The main function of is to call closeCallback_, This callback is bound to TcpServer::removeConnection(), The latter will put conn from ConnectionMap In the delete .
TcpConnection It didn't provide close() function , But use shutdown() function ,muduo The initiative to close the connection is divided into two steps : If you want to take the initiative to close the connection , First turn off the local “ Write ” End , Wait until the other party closes the connection , Then close the local “ read ” End , such half-close Mainly to prevent closing the connection , The other party is still sending data .
3、 ... and 、TcpConnection send data
By calling TcpConnection::send() To send data , Because the message must be read and written in EventLoop The same thread of , Therefore, thread safety must be ensured , So in send When , It will first check whether it is in the current IO Threads , If so, call directly sendInLoop(), If not in a thread , Will be able to messsage A copy of , Pass to IO In thread sendInLoop() To send the .
sendInLoop() Will try to send data directly , If you send it all at once , Will not enable WriteCallback, If only part of the data is sent , Then put the remaining data into outputBuffer_, And began to focus on writable event , And then in handleWrite() Send the remaining data in .
Four 、 How to limit the maximum number of concurrent connections to the server
Prepare an idle file descriptor , When the file descriptor used by this process has reached the upper limit (Acceptor Of handleRead() perform accept, return errno by EMFILE), First close the idle file descriptor , Get a quota for a file descriptor , Again accept() Get new socket The descriptor of the connection , And then immediately close() fall , This gracefully disconnects the client , Finally, reopen an idle file descriptor , hold “ pit ” Occupy , In case this happens again .
5、 ... and 、 How to kick off idle connections
Use timeing wheel, The approximate data structure is :8 A barrel (hash set) A circular queue ( Timeout time 8s). Put the first bucket 1 Connections that will time out in seconds , Put the second bucket 2 The connection that will time out after seconds, and so on , As soon as each connection receives the data, it puts itself into the 8 A barrel , Then in every second timer Disconnect the connection in the first bucket , Move this empty bucket to the end of the line . So you don't have to check all the connections every time .
The process of connection timeout being kicked out :


Connection refresh :

Concrete implementation , There is no connection in the bucket , It is Entry struct, Every Entry contain TcpConnection Of weak_ptr, When Entry The reference count of is decremented to 0, It means it doesn't exist in any box , The connection times out ,Entry The destructor of will disconnect .
6、 ... and 、 Flow control when sending data
muduo Set up WriteCompleteCallback() and HighWaterCallback() As “ Low water level callback ” and “ High water level callback ”, Called when the send buffer is empty WriteCompleteCallback(), When the length of the output buffer exceeds the size specified by the user , Just call HighWaterCallback().
7、 ... and 、 Why? TcpConnection Object is used shared_ptr To manage objects
Because from TCP The connection received a request Start , It may take some time for the program to process this connection , In order to confirm socket Connection is processing request Whether the period has been closed , Need to hold TcpConnection Reference count for object .
8、 ... and 、TcpConnection Of id How to store , When from client connection Receive the data , How to know id
TcpConnection Of id Use std::map<int, TcpConnectionPtr> clientConns_ preservation id To client connection Mapping ,muduo Of TcpConnection Also use context function , Every TcpConnection There is one. boost::any member , Can be used to save and connection Bound arbitrary data , For example, connection. id, Connection last data arrival time , The user name represented by the connection .
边栏推荐
- Ubuntu 14.04 下开启PHP错误提示
- 静态链表(数组的下标代替指针)
- 编程内功之编程语言众多的原因
- MapReduce implements matrix multiplication - implementation code
- Go language web development series 25: Gin framework: using MD5 to verify the signature for the interface station
- 【556. 下一个更大元素 III】
- 刚毕业的欧洲大学生,就能拿到美国互联网大厂 Offer?
- SVN添加文件时的错误处理:…\conf\svnserve.conf:12: Option expected
- Go language web development series 29: Gin framework uses gin contrib / sessions library to manage sessions (based on cookies)
- Go language web development series 27: Gin framework: using gin swagger to implement interface documents
猜你喜欢

AI scores 81 in high scores. Netizens: AI model can't avoid "internal examination"!

The latest BSC can pay dividends. Any B usdt Shib eth dividend destruction marketing can

Mastering the cypress command line options is the basis for truly mastering cypress

Go language web development series 28: solve cross domain access of CORS with gin contrib / CORS

Unity EmbeddedBrowser浏览器插件事件通讯

CVPR 2022 | 美团技术团队精选6篇优秀论文解读

Complete deep neural network CNN training with tensorflow to complete picture recognition case 2

Students who do not understand the code can also send their own token, which is easy to learn BSC

Kivy教程之 如何自动载入kv文件

Go language web development series 26: Gin framework: demonstrates the execution sequence of code when there are multiple middleware
随机推荐
Complete DNN deep neural network CNN training with tensorflow to complete image recognition cases
Asp.Net Core1.1版本没了project.json,这样来生成跨平台包
Kivy教程之 如何自动载入kv文件
JS 将伪数组转换成数组
Screenshot of the operation steps of upload labs level 4-level 9
[556. Next larger element III]
实现CNN图像的识别和训练通过tensorflow框架对cifar10数据集等方法的处理
Unity embeddedbrowser browser plug-in event communication
Libuv Library - Design Overview (Chinese version)
User and group command exercises
常见的几种最优化方法Matlab原理和深度分析
RichView TRVStyle ListStyle 列表样式(项目符号编号)
[sort] bucket sort
[redis] cache warm-up, cache avalanche and cache breakdown
Typeerror resolved: argument 'parser' has incorrect type (expected lxml.etree.\u baseparser, got type)
Go language web development series 25: Gin framework: using MD5 to verify the signature for the interface station
[how to earn a million passive income]
Record 405 questions about bank callback post request
Error running 'application' in idea running: the solution of command line is too long
挡不住了,国产芯片再度突进,部分环节已进到4nm