Muduo network programming example 0: Preface

Source: Internet
Author: User

Chen Shuo (giantchen_at_gmail)
Blog.csdn.net/solstice

Full muduo SeriesArticleList: http://blog.csdn.net/Solstice/category/779646.aspx
I will write a series of articles about using the muduo network library to complete common TCP network programming tasks. The current plan is as follows:

    1. Simple protocols in UNP, including ECHO, daytime, time, and discard.
    2. Example in boost. ASIO, including timer2 ~ 6. Chat.
    3. Examples in Java netty include discard, ECHO, and uptime. The discard and Echo Features include traffic statistics.
    4. Examples in Python twisted, including finger01 ~ 07
    5. Used to test the round-trip delay of two machines
    6. Pingpong used to test the bandwidth of two machines
    7. The yundun series and converts the connection Server Multiplexer, including single-line and multi-thread versions.
    8. File Transfer
    9. A tcp-based application layer broadcast Hub
    10. SOCKS4A proxy server, including simple TCP relay ).
    11. The evolution of a Sudoku server, from single thread to multi-thread, from blocking to event-based.
    12. An httpd server that provides the short address service

The first seven of them have been placed in muduo.CodeIn the examples directory of is: http://muduo.googlecode.com/files/muduo-0.1.5-alpha.tar.gz

These examples are simple, the logic is not complex, and the code is very short. It is suitable to extract key parts and put them on the blog. Some of them are representative and targeted. For example, it is estimated that "how to transmit complete files" is a common problem for beginners of network programming. Note that muduo is designed to develop Intranet networksProgramIt does not provide any security enhancement measures. If it is used on the Internet, it may be attacked. I will discuss this in the following example.

This series of articles applies to Linux 2.6.x (x> 28) and mainly tests the released versions of ubuntu 10.04 lts and Debian 6.0 squeeze, 64-bit x86 hardware.

TCP network programming

In my opinion, the most essential of TCP network programming is to handle three half events:

    1. Establish a connection, including accepting (accept) a new connection from the server and successfully initiating (CONNECT) a connection from the client.
    2. Disconnection, including active disconnection (close or shutdown) and passive disconnection (read returns 0 ).
    3. The message arrives and the file descriptor is readable. This is the most important event. The processing method determines the network programming style (blocking or non-blocking, how to handle subcontracting, and how to design the buffer at the application layer ).
    4. After the message is sent, this is half a message. For low-traffic services, you don't have to worry about this event. In addition, "sent" refers to writing data into the buffer zone of the operating system, the TCP stack is responsible for data transmission and retransmission, which does not mean that the other party has received the data.

There are many difficulties and many details to pay attention to, for example:

    1. If you want to proactively close the connection, how can you ensure that the other party has received all the data? If the application layer has a buffer (this is required in non-blocking network programming, see the following figure), how can we ensure that the data in the buffer is sent first and then disconnected. Directly calling close (2) may not work.
    2. If the connection is actively initiated but the other party refuses, how can I retry regularly (with back-off?
    3. Should I use edge trigger or level trigger for non-blocking network programming )? (These two Chinese terms are translated in other ways. I chose an electronic engineer familiar with them .) If it is a level-based trigger, when will the epollout event be followed? Will it cause busy-loop? If it is triggered by edge, how can we prevent the hunger caused by missing reading? Must epoll be faster than poll?
    4. In non-blocking network programming, why should I use the application layer buffer? If the data read at a time is not enough to have a complete data packet, should the read data be saved somewhere and processed after the remaining data is received? See the bug in \ r \ n subcontracting in Lighttpd. If the data arrives at one byte in one byte at a 10 ms interval, can the program still work if each byte triggers a file descriptor readable event? Lighttpd has a security vulnerability on this issue.
    5. In non-blocking network programming, how do I design and use a buffer? On the one hand, we want to reduce system calls. The more data we read at a time, the more cost-effective it is. It seems that we should prepare a large buffer zone. On the other hand, our system reduces memory usage. If there are 10 k connections, each connection will allocate a 64 K read buffer as soon as it is established, it will occupy 640 MB of memory, and most of the time the buffer usage is very low. Muduo uses readv in combination with the space on the stack to cleverly solve this problem.
    6. If the sending buffer is used, will the data always accumulate on the sender in case of slow processing by the receiver, resulting in a high memory usage? How to control traffic at the application layer?
    7. How to design and implement a timer? And it shares a thread with the network Io to avoid the lock.

These questions can be found in muduo's code.

Muduo Introduction

One of the purposes of writing a muduo network library is to simplify the daily TCP network programming, so that programmers can focus on the implementation of business logic, rather than competing with the Sockets API every day. I want muduo to reduce the occasional complexity (accidental complexity) in network programming, in the words of Brooks ).

Muduo only supports concurrent and non-blocking TCP network programming under Linux 2.6.x. For the installation method, see Chen Shuo's blog article.

Muduo is easy to use. You do not need to derive from the specified class or overwrite the virtual function. You only need to register several callback functions to process the three and a half events mentioned above.

Take the classic Echo service as an example:

1. Define the echoserver class and do not need to be derived from any base class:
  1   # Ifndef muduo_examples_simple_echo_echo_h
2   # Define Muduo_examples_simple_echo_echo_h
3 # Include < Muduo / Net / Tcpserver. h >
4   // RFC 862
5   Class Echoserver
6 {
7   Public :
8 Echoserver (muduo: Net: eventloop * Loop,
9 Const Muduo: Net: inetaddress & Listenaddr );
10 Void Start ();
11   Private :
12 Void Onconnection ( Const Muduo: Net: tcpconnectionptr & Conn );
13 Void Onmessage ( Const Muduo: Net: tcpconnectionptr & Conn,
14 Muduo: Net: Buffer * Buf,
15 Muduo: Timestamp time );
16 Muduo: Net: eventloop * Loop _;
17 Muduo: Net: tcpserver server _;
18 };
19   # Endif // Muduo_examples_simple_echo_echo_h
Register the callback function in the constructor:
 1   Echoserver: echoserver (eventloop  *  Loop,
2 Const Inetaddress & Listenaddr)
3 : Loop _ (loop ),
4 Server _ (loop, listenaddr, " Echoserver " )
5 {
6 Server _. setconnectioncallback (
7 Boost: BIND ( & Echoserver: onconnection, This , _ 1 ));
8 Server _. setmessagecallback (
9 Boost: BIND ( & Echoserver: onmessage, This , _ 1, _ 2, _ 3 ));
10 }
11
12   Void Echoserver: Start ()
13 {
14 Server _. Start ();
15 }

 

2. Implement echoserver: onconnection () and echoserver: onmessage ():
  1   Void  Echoserver: onconnection (  Const  Tcpconnectionptr  &  Conn)
2 {
3 Log_info < " Echoserver- " < Conn -> Peeraddress (). tohostport () < " -> "
4 < Conn -> Localaddress (). tohostport () < " Is "
5 < (Conn -> Connected () ? " Up " : " Down " );
6 }
7
8 Void Echoserver: onmessage ( Const Tcpconnectionptr & Conn,
9 Buffer * Buf,
10 Timestamp time)
11 {
12 String MSG (Buf -> Retrieveasstring ());
13 Log_info < Conn -> Name () < " Echo " < MSG. Size () < " Bytes " < Time. tostring ();
14 Conn -> Send (MSG );
15 }
3. Use eventloop in main () to run the entire program:
  1  # Include  "  Echo. h  "  
2 # Include < Muduo / Base / Logging. h >
3 # Include < Muduo / Net / Eventloop. h >
4 Using Namespace Muduo;
5   Using Namespace Muduo: net;
6   Int Main ()
7 {
8 Log_info < " PID = " < Getpid ();
9 Eventloop loop;
10 Inetaddress listenaddr ( 2007 );
11 Echoserver server ( & Loop, listenaddr );
12 Server. Start ();
13 Loop. Loop ();
14 }

For the complete code, see muduo/examples/simple/ECHO.

The dozens of rows of applets implement a concurrent echo service program that can process multiple connections at the same time.

For detailed analysis of this program, see the next blog muduo network programming example: Five Simple TCP Protocols

(To be continued)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.