Libevent process of one package

Source: Internet
Author: User
// The first package of a packet sending process is the heartbeat package of the client. Now we have added a version package to check the package packaging process. The process persists, but it is hard to understand void NGP :: onlivetimer () // client heartbeat, send once every 5s {sendcmd (c2s_on_live, null, 0);} bool NGP: sendcmd (INT ncmd, void * pdata, int nlen) {// STD: wstring MSG = l "sending command:"; // MSG + = boost: lexical_cast <STD: wstring> (CMD ); // m_share-> log (MSG. c_str (); // sends the request for obtaining the game list protocol RPT = {0}; Rpt. performance_type = ncmd; Rpt. content = pdata; Rpt. size = nlen; STD: vector <char> buffer; Buffer. resize (nlen + sizeof (Protocol); // This length is personally acceptable-sizeof (void *). This position is actually overwritten int send_len = Rpt. to_buffer (& buffer [0], buffer. size (); For (;) {bool B = m_sptcplink-> send (& buffer [0], send_len); If (B) break; STD: this_thread :: sleep_for (STD: chrono: milliseconds (5);} return true;} // package format (this is the format of the initial packet sending)-(one byte Protocol) ---- (the length of four bytes indicates the size of the subsequent content) --------------- (Package content) struct Protocol {unsigned char pai_type; Int size; // content length, excluding the void * Content Header of this Protocol; int to_buffer (void * buffer, int buffer_len) // {If (! Buffer) Return-1; int total_size = size + sizeof (Protocol)-sizeof (void *); //-sizeof (void *) it is because if (buffer_len <total_size) that is copied from the pointer position is the provided memory size, and total_size is the total size after packaging. Return-1; protocol * P = (Protocol *) buffer; // regard the memory model as the protocol model P-> protocol _type = This-> protocol _type; P-> size = This-> size; if (content) {memcpy (& P-> content, content, size); // copy the content from the beginning of the pointer} return total_size ;}} // This package has another one in libevent Packaging Process ---- (4 bytes, indicating the total length of the backbread)-(one-byte protocol) ---- (the length of the four bytes indicates the size of the subsequent content) ----------------- (Package content) therefore, the length of the heartbeat packet is 9 bytes. // The read event of the process thread that the server receives is called/* read data stream */void channel :: read_datastream (struct bufferevent * BEV) {// bufferevent_read reads the data in the input buffer each time. It seems that up to 4096 bytes can be read. Therefore, such a large amount of data may be multiple packages, another possibility is that none of the packages will be available. This is a problem: size_t Len = bufferevent_read (BEV, m_buf, sizeof (m_buf);/*** [test]: Unlock first and lock again, prevent the send_data of main_thread from being blocked when the thread waits for an endless loop when memory allocation fails. */Evbuffer_unlock (Bev-> output); // Auto & in = Bev-> input; same as lock // Auto & out = Bev-> output; m_readstream.push (m_buf, len); // datastream is equivalent to a buffer. In this process, I understand the waste, and finally I learned about read_pack () with the help of both (); evbuffer_lock (Bev-> output);} void push (const void * pbuf, int nlen) {char * pbuf2 = (char *) pbuf; m_streambuffer.insert (m_streambuffer.end (), pbuf2, pbuf2 + nlen); // Insert the package to the last position each time}/* read package */void channel: read_pack () {If (m_readstream.size () <4) // If the size is smaller than 4, it indicates that the read is finished, and there cannot be a packet smaller than 4 bytes. It may be an incomplete package return; size_t Len = * (size_t *) m_readstream.peek (); // obtain the first four bytes, indicating the length of the Package content. If (m_readstream.size () <4 + Len) // indicates that the package does not comply with the rules. It should >=, of course, it may also be because this package is incomplete. Wait for the next time to parse return; m_event-> on_receive_data (m_id, m_readstream.peek () + 4, Len ); // process the package m_readstream.pop (4 + Len); // each package escaped from the next read location read_pack (); // until it has been read} void POP (INT nlen) {m_head_size + = nlen; // move the header flag if (m_head_size> m_buff_len) {// This array can be used as a cyclic queue, there is also a way to use cyclic queue: Two cursors: m_streambuffer.erase (m_streambuffer.begin (), m_streambuffer.begin () + m_head_size); // Delete and reserve again, which may prevent reading errors, not clear: m_head_size = 0; m_streambuffer.reserve (m_buff_len );}}

There are still many things to do about the final arrival of Gs. We can analyze this for the time being.

Libevent process of one package

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.