www.pudn.com > GGBT.rar > Connection.cpp


// Connection.cpp: implementation of the CConnection class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "testbt.h" 
#include "Connection.h" 
 
 
#include "Encrypter.h" 
#include "Upload.h" 
#include "SingleDownload.h" 
 
#include "Connector.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
char* tobinary(long lnum, char* pBuf, long length=4); 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CConnection::CConnection(CEncryptedConnection* pEConnection, CConnector* pConnector) 
{ 
	m_pEConnection = pEConnection; 
	m_pConnector = pConnector; 
 
	m_bGotAnything = false; 
	m_pUpload = 0; 
	m_pDownload = 0; 
	 
	m_bPause = false; 
 
	 
	m_lIndex = 0; 
	memset(m_lValueUp, 0, eCount*sizeof(long)); 
	memset(m_lValueDown, 0, eCount*sizeof(long)); 
} 
 
CConnection::~CConnection() 
{ 
} 
 
void CConnection::GetRate(long& lDownRate, long & lUpRate)  
{ 
	lDownRate = m_pDownload->get_rate(); 
	lUpRate = m_pUpload->get_rate(); 
 
	if (--m_lIndex < 0) 
	{ 
		m_lIndex = eCount - 1; 
	} 
	 
	m_lValueUp[m_lIndex] = lUpRate/1024; 
	m_lValueDown[m_lIndex] = lDownRate/1024; 
} 
 
string CConnection::GetIP() 
{ 
	return m_pEConnection->GetIP(); 
} 
 
bool CConnection::GetIP(long& lAddr, short& sPort) 
{ 
	return m_pEConnection->GetIP(lAddr, sPort); 
} 
 
memstream& CConnection::GetID() 
{ 
	return m_pEConnection->GetID(); 
} 
 
void CConnection::Close() 
{ 
	m_pEConnection->Close(); 
} 
 
bool CConnection::IsFlush() 
{ 
	if (m_pConnector->IsRatecap() || IsPause()) 
		return false; 
	return m_pEConnection->IsFlush(); 
} 
 
bool CConnection::is_locally_initiated() 
{ 
	return m_pEConnection->is_locally_initiated(); 
} 
 
void CConnection::send_interested() 
{ 
	char c = INTERESTED; 
	m_pEConnection->send_message(&c, sizeof(char)); 
} 
 
void CConnection::send_not_interested() 
{	 
	char c = NOT_INTERESTED; 
	m_pEConnection->send_message(&c, sizeof(char)); 
} 
 
void CConnection::send_choke() 
{ 
	char c = CHOKE; 
	m_pEConnection->send_message(&c, sizeof(char)); 
} 
 
void CConnection::send_unchoke() 
{ 
	char c = UNCHOKE; 
	m_pEConnection->send_message(&c, sizeof(char)); 
} 
 
void CConnection::send_request(long index, long begin, long length) 
{	 
	char lenBuf[4] = {0}; 
 
	char c = REQUEST; 
	memstream memtemp; 
	memtemp.write(&c, 1); 
	memtemp.write(tobinary(index, lenBuf), sizeof(long)); 
	memtemp.write(tobinary(begin, lenBuf), sizeof(long)); 
	memtemp.write(tobinary(length, lenBuf), sizeof(long)); 
 
	// m_pConnector->got_message(m_pEConnection, memtemp, memtemp.size()); 
 
	m_pEConnection->send_message(memtemp, memtemp.size()); 
} 
 
void CConnection::send_cancel(long index, long begin, long length) 
{ 
	char lenBuf[4] = {0}; 
	char c = CANCEL; 
	memstream memtemp; 
	memtemp.write(&c, 1); 
	memtemp.write(tobinary(index, lenBuf), sizeof(long)); 
	memtemp.write(tobinary(begin, lenBuf), sizeof(long)); 
	memtemp.write(tobinary(length, lenBuf), sizeof(long)); 
	m_pEConnection->send_message(memtemp, memtemp.size()); 
} 
 
void CConnection::send_piece(long index, long begin, memstream& piece) 
{ 
	assert(!m_pConnector->IsRatecap()); 
	m_pConnector->_update_upload_rate(piece.size()); 
 
	char lenBuf[4] = {0}; 
	char c = PIECE; 
	memstream memtemp; 
	memtemp.write(&c, 1); 
	memtemp.write(tobinary(index, lenBuf), sizeof(long)); 
	memtemp.write(tobinary(begin, lenBuf), sizeof(long)); 
	memtemp.write(piece, piece.size()); 
	m_pEConnection->send_message(memtemp, memtemp.size()); 
	 
} 
 
void CConnection::send_bitfield(vector& vHave) 
{ 
 
	char c = BITFIELD; 
	memstream memtemp; 
	memtemp.write(&c, 1); 
	 
	memstream mret; 
	booleans_to_bitfield(vHave, mret); 
	memtemp.write(mret, mret.size()); 
 
	m_pEConnection->send_message(memtemp, memtemp.size()); 
} 
 
void CConnection::send_have(long index) 
{ 
	char lenBuf[4] = {0}; 
	char c = HAVE; 
	memstream memtemp; 
	memtemp.write(&c, 1); 
	memtemp.write(tobinary(index, lenBuf), sizeof(long)); 
	m_pEConnection->send_message(memtemp, memtemp.size()); 
} 
 
bool CConnection::IsPause() 
{ 
	return m_bPause; 
} 
 
void CConnection::Pause(bool bPause) 
{ 
	if (IsPause() == bPause) 
	{ 
		assert(false); 
		return; 
	} 
 
	m_bPause = bPause; 
 
	if (!bPause) 
	{ 
		if (m_pDownload) 
			m_pDownload->download_more(); 
	} 
} 
 
/* 
	long l = 17; 
	char a[20] = {0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}; 
	memstream m, mret, memsrc; 
	m.write(a, l); 
	booleans_to_bitfield1(m, mret); 
	unsigned char b[30] = {0}; 
	memcpy(b, mret, mret.size()); 
	 
	bitfield_to_booleans(mret, l, memsrc); 
	memcpy(b, memsrc, memsrc.size()); 
	assert(memsrc == m); 
 
	//*/ 
void booleans_to_bitfield(vector& vHave, memstream& memRet) 
{ 
	assert(vHave.size() > 0);	 
 
	unsigned char p = 0x80; 
	unsigned char c = 0; 
 
	for (int i=0; i>= 1; 
 
		if ((i+1)%8 == 0) 
		{ 
			memRet.write((char*)&c, 1); 
			p = 0x80; 
			c = 0; 
		} 
	} 
	if (i%8 != 0) 
		memRet.write((char*)&c, 1); 
} 
 
bool bitfield_to_booleans(memstream& membitfield, long lNumPieces, vector& vHave) 
{ 
	assert(membitfield.size() > 0 && lNumPieces > 0); 
 
	long lextra = membitfield.size()* 8 - lNumPieces; 
	if (lextra >= 8 || lextra < 0) 
	{ 
		assert(false); 
		return false; 
	} 
 
	for (int i=0; i>= 1; 
 
			if (--lNumPieces <= 0) 
				break; 
		} 
	} 
	return true; 
}