Developers.Code.CNeighbour: Difference between revisions

From Shareaza Wiki
Jump to navigation Jump to search
(Importing page from Tikiwiki)
 
m (1 revision)
 

Latest revision as of 20:07, 20 June 2009

CNeighbour

The CNeighbour class inherits from CConnection. In CNeighbour.h, the class defines a big group of member variables that are useful for all the networks that Shareaza browses. In CNeighbour.cpp, the class builds on the socket features of CConnection by adding Zlib compression.

Constructor and Destructor

The constructor is overloaded, which means there are two different versions. One takes a protocol ID alone, while the other also takes a pointer to another CNeighbour object called pBase. The first overload of the constructor saves the given protocol ID in m_nProtocol, and gives all the other member variables zero, null, or default values. The second constructor overload copies values from pBase instead.

The destructor shuts down zlib compression if necessary, and deletes attached objects.

Close and DelayClose

Call Close to close the connection with the other computer. The method removes this object from the program's record of neighbours, and has the connection class terminate the socket.

If you have data waiting in the output buffer that should be sent to the remote computer before closing the connection, DelayClose can help. It calls CConnection::QueueRun, the method that uses m_nQueuedRun to delay a write.

Send and SendQuery

These methods seem to be designed to send packets and query packets, but don't contain enough code to do anything.

OnRun

The OnRun method checks to make sure the connection hasn't gone silent too long, and sends a query patch table if necessary.

OnDropped

Logs an application message about how long the connection has been open, and how long it's been since we've received a packet over it. Then, OnDropped closes the connection citing the reason as dropped.

OnRead and OnWrite

Both CConnection and CNeighbour have OnRead and OnWrite methods. In CConnection, OnRead and OnWrite pass data through the socket. Here in CNeighbour, the methods are in charge of data compression.

OnRead and OnWrite are very similar because each they carry out the same operation in two different directions. OnRead gets data from the socket, and then has the Zlib inflate function decompress it. OnWrite compresses data with deflate, and then sends it through the socket. In OnRead, the compressed data is in a buffer called m_pInput, and gets decompressed to m_pZInput. OnWrite compresses data from m_pZOutput to m_pOutput.

Shareaza uses the Zlib library to compress and decompress data. To use Zlib, make a z_stream structure. Then, tell it what to compress, and where to put the compressed data. Here is the code which does this in OnWrite.

[code OnWrite] pStream->next_in = m_pZOutput->m_pBuffer; pStream->avail_in = m_pZOutput->m_nLength; pStream->next_out = m_pOutput->m_pBuffer + m_pOutput->m_nLength; pStream->avail_out = m_pOutput->m_nBuffer - m_pOutput->m_nLength; </source>

The pointer pStream points to the z_stream structure. Inside are two pointers and two lengths. The first pointer, next_in, tells Zlib where the data it should work on is located. Right after that, avail_in indicates how much data is there.

The pointer and length pair next_out and avail_out clip out a region of memory also. This is the region of empty space in the m_pOutput buffer where Zlib can write compressed data. Developers.Topic.BuffersAndLengths

The Zlib inflate and deflate functions move these pointers and change these lengths to report what Zlib did. Zlib moves next_in to the right, past the data that it compressed. Zlib makes avail_in smaller by the same amount. To show how much data Zlib wrote, it moves next_out to the right and makes avail_out smaller. So, if avail_in reaches 0, Zlib has no more data to compress. If avail_out reaches 0, it has no more space.

OnCommonHit and OnCommonQueryHash

These methods handle Gnutella packets. I will document them later.

GetCompression

GetCompression calculates the compression rate for data coming in and going out through the socket. The bandwidth meter counts the bytes that pass through the socket. When compression is on, all of these bytes will be compressed. So, both m_mInput.nTotal and m_mOutput.nTotal are counts of compressed bytes. The m_pInput and m_pOutput buffers sit right next to the socket, and contain compressed data. OnRead decompresses incoming data to m_pZInput, and OnWrite compresses outgoing data from m_pZOutput. So, both m_nZInput and m_nZOutput contain data that isn't compressed.

The GetCompression method uses the following equation to calculate compression rates:

1 - ( compressed size / normal size )

So, if 100 bytes are just 80 when compressed, the calculated rate will be 1 - (80 / 100), or 0.2.