Encrypter.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:8k
源码类别:
P2P编程
开发平台:
Visual C++
- // Encrypter.cpp: implementation of the CEncrypter class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testbt.h"
- #include "Encrypter.h"
- #include "Download.h"
- #include "Connector.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- void CEncrypter::InitLocalIps()
- {
- char szHostName[128];
- if( gethostname(szHostName, 128) == 0 )
- {
- // const char* pszAddr;
- struct hostent * pHost;
- pHost = gethostbyname(szHostName);
- for(int i=0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
- {
- /*对每一个IP地址进行处理*/
- // pszAddr=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]);
- m_vlocalIps.push_back((long)(*(struct in_addr *)pHost->h_addr_list[i]).S_un.S_addr);
- }
- if (m_vlocalIps.empty())
- {
- assert(false);
- }
- }
- else
- {
- assert(false);
- }
- }
- CEncrypter::CEncrypter(long lMaxInitiate)
- {
- m_lMaxInitiate = lMaxInitiate;
- }
- bool CEncrypter::Create(CDownloaderFeedback* pMain, CConnector * pconnector, memstream& memMyid, memstream& memInfohash, long lMaxLen, long lKeepaliveDelay)
- {
- m_pMain = pMain;
- m_pconnector = pconnector;
- m_memMyId.write(memMyid, memMyid.size());
- m_memInfohash.write(memInfohash, memInfohash.size());
- m_lMaxLen = lMaxLen;
- m_lKeepaliveDelay = lKeepaliveDelay;
- time(&m_lKeepaliveDelayLast);
- // for socket id.
- m_lConnectionIDSeed = 100;
- InitLocalIps();
- return true;
- }
- CEncrypter::~CEncrypter()
- {
- for (int i=0; i<m_connections.size(); i++)
- delete m_connections[i];
- for (i=0; i<m_unConnections.size(); i++)
- {
- closesocket(m_unConnections[i]->m_socket);
- CloseHandle(m_unConnections[i]->m_hevConnecting);
- delete m_unConnections[i];
- }
- }
- void CEncrypter::SetMaxPeers(long lMaxInitiate)
- {
- m_lMaxInitiate = lMaxInitiate;
- }
- long CEncrypter::GetMaxLen()
- {
- return m_lMaxLen;
- }
- long CEncrypter::send_keepalives()
- {
- long ltime = 0;
- time(<ime);
- if ( (ltime-m_lKeepaliveDelayLast) < m_lKeepaliveDelay)
- return m_lKeepaliveDelay - (ltime - m_lKeepaliveDelayLast);
- for (int i=0; i<m_connections.size(); i++)
- {
- m_connections[i]->send_message("", 0);
- }
- time(&m_lKeepaliveDelayLast);
- return m_lKeepaliveDelay;
- }
- void CEncrypter::connection_made(SOCKET newsocket)
- {
- // if (m_connections.size() < m_lMaxInitiate)
- if ((m_connections.size() + m_unConnections.size() + 3) < MAXIMUM_WAIT_OBJECTS && // 3 handles for other event to handle
- m_pconnector->m_connections.size() < m_lMaxInitiate)
- {
- CEncryptedConnection* pnew = new CEncryptedConnection(m_pMain, newsocket, m_pconnector, this, memstream(), m_lConnectionIDSeed ++);
- m_connections.push_back(pnew);
- pnew->connection_init();
- // m_pMain->ShowEncryptedMessage(string("accepted to peers : ") + pnew->GetIP());
- }
- else
- {
- closesocket(newsocket);
- // m_pMain->ShowEncryptedMessage(string("Close a accepted peers, because of too may connections"));
- }
- }
- void CEncrypter::start_connection(string strIP, short lPort, memstream &mPeerID)
- {
- // check peer whether connected.
- if ((m_connections.size() + m_unConnections.size() + 3) >= MAXIMUM_WAIT_OBJECTS || // 3 handles for other event to handle
- m_pconnector->m_connections.size() >= m_lMaxInitiate)
- {
- m_pMain->ShowEncryptedMessage(string("Close a connected peers, because of too may connections"));
- return;
- }
- if (mPeerID == m_memMyId)
- return ;
- //
- // if peer info is self, skip it.
- //
- for (int i=0; i<m_connections.size(); i++)
- {
- if (mPeerID == m_connections[i]->m_memPeerid)
- return;
- }
- //
- // if peer addr no valid skip it.
- //
- unsigned long laddr = inet_addr(strIP.data());
- if (laddr == INADDR_NONE)
- {
- m_pMain->errorFunc("start_connection error : the peer ip is invalid");
- return;
- }
- //
- // if the peer is self ip, skip it.
- //
- for (i=0; i<m_vlocalIps.size(); i++)
- {
- if (laddr == m_vlocalIps[i])
- {
- #ifdef _DEBUG
- in_addr inaddress;
- inaddress.S_un.S_addr = laddr;
- const char* pszAddr = inet_ntoa(inaddress);
- char szText[1024] = {0};
- sprintf(szText, "rn %s connect to self, the peer is left at the server by last runrn", pszAddr);
- TRACE(szText);
- #endif
- return;
- }
- }
- //
- // try to connect the peer.
- //
- SOCKET hnewSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
- if (hnewSocket == INVALID_SOCKET)
- {
- m_pMain->errorFunc("start_connection error:can't create socket");
- return ;
- }
- HANDLE hevConnecting = ::CreateEvent(0, false, false, 0);
- assert(hevConnecting);
- int iRet = WSAEventSelect(hnewSocket, hevConnecting , FD_CONNECT);
- if (iRet == SOCKET_ERROR)
- {
- assert(false);
- string e = WSAShowError();
- return;
- }
- //*
- sockaddr_in addr = {0};
- addr.sin_family = AF_INET;
- addr.sin_port = htons(lPort);
- addr.sin_addr.S_un.S_addr = laddr;
- int ilen = sizeof(addr);
- iRet = connect(hnewSocket, (sockaddr*)&addr, ilen);
- if (iRet != 0)
- {
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- assert(false);
- }
- m_unConnections.push_back(new CUnConnectedSocket(hnewSocket, hevConnecting, laddr, lPort, mPeerID));
- }
- void CEncrypter::complete_connecting(long lInx)
- {
- vector<CUnConnectedSocket*>::iterator iter = m_unConnections.begin() + lInx;
- assert(iter != m_unConnections.end());
- WSANETWORKEVENTS events;
- int iRet = WSAEnumNetworkEvents((*iter)->m_socket, (*iter)->m_hevConnecting, &events);
- if (iRet == SOCKET_ERROR)
- {
- string e = WSAShowError();
- assert(false);
- return;
- }
- if (!(events.lNetworkEvents & FD_CONNECT))
- return;
- int iErrCode = events.iErrorCode[FD_CONNECT_BIT];
- if (iErrCode != 0) // connect error.
- {
- switch (iErrCode)
- {
- case WSAEAFNOSUPPORT:
- break;
- case WSAECONNREFUSED:
- break;
- case WSAENETUNREACH:
- break;
- case WSAENOBUFS:
- break;
- case WSAETIMEDOUT:
- break;
- default:
- {
- iRet = 0;
- }
- break;
- }
- closesocket((*iter)->m_socket);
- }
- else
- {
- if ((m_connections.size() + m_unConnections.size() + 3) < MAXIMUM_WAIT_OBJECTS && // 3 handles for other event to handle
- m_pconnector->m_connections.size() < m_lMaxInitiate)
- {
- // TRACE("rnall, connected : %d, %drn", (m_connections.size() + m_unConnections.size()), m_pconnector->m_connections.size());
- CEncryptedConnection* pnew = new CEncryptedConnection(m_pMain, (*iter)->m_socket, m_pconnector, this, (*iter)->m_mPeerID, m_lConnectionIDSeed ++);
- m_connections.push_back(pnew);
- pnew->connection_init();
- m_pMain->ShowEncryptedMessage(string("connected to peers : ") + pnew->GetIP());
- }
- else // too many connections to handle. WaitForMultipleObjects only can handle count of MAXIMUM_WAIT_OBJECTS.
- {
- closesocket((*iter)->m_socket);
- m_pMain->ShowEncryptedMessage(string("Close a connected peers, because of too may connections"));
- }
- }
- // release select event.
- // WSAEventSelect((*iter)->m_socket, (*iter)->m_hevConnecting, 0);
- CloseHandle((*iter)->m_hevConnecting);
- delete (*iter);
- iter = m_unConnections.erase(iter) - 1 ;
- }
- bool CEncrypter::detele_connections_died()
- {
- for (int i=0; i<m_connections_died.size(); i++)
- {
- CEncryptedConnection* pdied = m_connections_died[i];
- vector<CEncryptedConnection*>::iterator it =
- find(m_connections.begin(), m_connections.end(), pdied);
- assert(it != m_connections.end());
- pdied->CloseDied();
- }
- m_connections_died.erase(m_connections_died.begin(), m_connections_died.end());
- return true;
- }