亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sockclient.cpp

?? 一些初級的網絡編程
?? CPP
字號:
// SockClient.cpp : implementation file
//

#include "stdafx.h"
#include "TcpHoleSrv.h"
#include "SockClient.h"
#include <Afxmt.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CPtrArray g_PtrAry_SockClient;
CCriticalSection g_CSFor_PtrAry_SockClient;
extern BOOL g_bDeleteNullSockClient;
DWORD g_nSockClientID = 0;

CSockClient* GetNewSockClient ()
{
	CSockClient *pSockClient = new CSockClient;
	if ( !pSockClient )
	{
		printf ( "New SockClient object failed\n" );
		return NULL;
	}
	g_CSFor_PtrAry_SockClient.Lock();
	g_PtrAry_SockClient.Add ( pSockClient );
	pSockClient->m_dwID = ++g_nSockClientID;
	g_CSFor_PtrAry_SockClient.Unlock();
	printf ( "Current SocketClient array count is %d\n", g_PtrAry_SockClient.GetSize() );

	return pSockClient;
}

//
// 將新客戶端登錄信息發送給所有已登錄的客戶端,但不發送給自己
//
BOOL SendNewUserLoginNotifyToAll ( LPCTSTR lpszClientIP, UINT nClientPort, DWORD dwID )
{
	ASSERT ( lpszClientIP && nClientPort > 0 );
	g_CSFor_PtrAry_SockClient.Lock();
	for ( int i=0; i<g_PtrAry_SockClient.GetSize(); i++ )
	{
		CSockClient *pSockClient = (CSockClient*)g_PtrAry_SockClient.GetAt(i);
		if ( pSockClient && pSockClient->m_bMainConn && pSockClient->m_dwID > 0 && pSockClient->m_dwID != dwID )
		{
			if ( !pSockClient->SendNewUserLoginNotify ( lpszClientIP, nClientPort, dwID ) )
			{
				g_CSFor_PtrAry_SockClient.Unlock();
				return FALSE;
			}
		}
	}

	g_CSFor_PtrAry_SockClient.Unlock ();
	return TRUE;
}

CSockClient* FindSocketClient ( DWORD dwID )
{
	g_CSFor_PtrAry_SockClient.Lock ();
	for ( int i=0; i<g_PtrAry_SockClient.GetSize(); i++ )
	{
		CSockClient *pSockClient = (CSockClient*)g_PtrAry_SockClient.GetAt(i);
		if ( pSockClient && pSockClient->m_dwID == dwID )
		{
			g_CSFor_PtrAry_SockClient.Unlock ();
			return pSockClient;
		}
	}
	printf ( "Can't find ID:%u\n", dwID );
	g_CSFor_PtrAry_SockClient.Unlock ();
	return NULL;
}

void DeleteNullSocketClient ()
{
	g_bDeleteNullSockClient = FALSE;
	g_CSFor_PtrAry_SockClient.Lock ();
	for ( int i=0; i<g_PtrAry_SockClient.GetSize(); i++ )
	{
		CSockClient *pSockClient = (CSockClient*)g_PtrAry_SockClient.GetAt(i);
		if ( pSockClient && pSockClient->m_dwID == 0 )
		{
			delete pSockClient;
			g_PtrAry_SockClient.RemoveAt(i);
			i --;
		}
	}
	printf ( "Current SocketClient array count is %d\n", g_PtrAry_SockClient.GetSize() );
	g_CSFor_PtrAry_SockClient.Unlock ();
}

DWORD WINAPI ThreadProc_SockClient(
  LPVOID lpParameter   // thread data
)
{
	CSockClient *pSockClient = reinterpret_cast<CSockClient*>(lpParameter);
	if ( pSockClient )
		return pSockClient->ThreadProc_SockClient ();
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CSockClient

CSockClient::CSockClient()
	: m_dwID ( 0 )
	, m_nPeerPort ( 0 )
	, m_hThread ( NULL )
	, m_hEvtEndModule ( NULL )
	, m_hEvtWaitClientBHole ( NULL )
	, m_dwThreadID ( 0 )
	, m_bMainConn ( FALSE )
{
}

CSockClient::~CSockClient()
{
	this->CancelBlockingCall ();
	if ( HANDLE_IS_VALID(m_hEvtEndModule) )
		::SetEvent ( m_hEvtEndModule );
	WaitForThreadEnd ( &m_hThread );
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CSockClient, CSocket)
	//{{AFX_MSG_MAP(CSockClient)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CSockClient member functions

//
// 和客戶端建立連接
//
BOOL CSockClient::EstablishConnect(SOCKET hSock, SOCKADDR_IN &sockAddr, BOOL bMainConn)
{
	ASSERT ( HANDLE_IS_VALID(hSock) );
	m_csPeerAddress = inet_ntoa(sockAddr.sin_addr);
	m_nPeerPort = ntohs(sockAddr.sin_port);
	m_hSocket = hSock;
	m_bMainConn = bMainConn;

	if ( m_bMainConn )
	{
		if ( !SendNewUserLoginNotifyToAll ( m_csPeerAddress, m_nPeerPort, m_dwID ) )
			return FALSE;
		printf ( "[MAIN SOCKET] New connection ( %s:%d:%u ) come in\n", m_csPeerAddress, m_nPeerPort, m_dwID );
	}
	else
	{
		printf ( "<HOLE SOCKET> New connection ( %s:%d:%u ) come in\n", m_csPeerAddress, m_nPeerPort, m_dwID );
	}

	// 創建一個線程來處理該客戶端的所有數據通信
	ASSERT ( m_hEvtEndModule == NULL && m_hEvtWaitClientBHole == NULL && m_hThread == NULL );
	m_hEvtEndModule = ::CreateEvent ( NULL, TRUE, FALSE, NULL );
	m_hEvtWaitClientBHole = ::CreateEvent ( NULL, FALSE, FALSE, NULL );
	m_hThread = ::CreateThread ( NULL, 0, ::ThreadProc_SockClient, this, 0, &m_dwThreadID );
	if ( !HANDLE_IS_VALID(m_hThread) || !HANDLE_IS_VALID(m_hEvtEndModule) || !HANDLE_IS_VALID(m_hEvtWaitClientBHole) )
		return FALSE;

	return TRUE;
}

//
// 將其他新登錄的客戶端信息發送給該客戶端
//
BOOL CSockClient::SendNewUserLoginNotify(LPCTSTR lpszClientIP, UINT nClientPort, DWORD dwID)
{
	ASSERT ( lpszClientIP && nClientPort > 0 );
	if ( !m_bMainConn ) return TRUE;
	t_NewUserLoginPkt NewUserLoginPkt;
	STRNCPY_SZ ( NewUserLoginPkt.szClientIP, lpszClientIP );
	NewUserLoginPkt.nClientPort = nClientPort;
	NewUserLoginPkt.dwID = dwID;
	printf ( "Send new user login notify to (%s:%u:%u)\n", m_csPeerAddress, m_nPeerPort, m_dwID );
	return ( SendChunk ( &NewUserLoginPkt, sizeof(t_NewUserLoginPkt), 0 ) == sizeof(t_NewUserLoginPkt) );
}

BOOL CSockClient::ThreadProc_SockClient()
{
	printf ( "Client.%u thread start.\n", m_dwID );
	BOOL bRet = FALSE;
	char szRecvBuffer[NET_BUFFER_SIZE] = {0};
	int nRecvBytes = 0;

	// WinSocket 的句柄是不能跨線程訪問的,所以這里重新附加進來
	if ( !Attach ( m_hSocket ) )
		goto finished;

	// 發送歡迎信息,通知客戶端連接成功了。
	SendWelcomeInfo ();
	// 循環接收網絡數據
	while ( TRUE )
	{
		nRecvBytes = Receive ( szRecvBuffer, sizeof(szRecvBuffer) );
		if ( nRecvBytes > 0 )
		{
			if ( !HandleDataReceived ( szRecvBuffer, nRecvBytes ) )
				goto finished;
		}
		else if ( (nRecvBytes == 0 && GetLastError() != NO_ERROR) || (SOCKET_ERROR == nRecvBytes && GetLastError() == WSAEWOULDBLOCK) )
		{
			SLEEP_BREAK ( 10 );
		}
		// 對方斷開連接了
		else
		{
			goto finished;
		}
		SLEEP_BREAK ( 1 );
	}

	bRet = TRUE;
finished:
	Close ();
	printf ( "Client.%u thread end. result : %s\n", m_dwID, bRet?"SCUESS":"FAILED" );
	if ( HANDLE_IS_VALID(m_hEvtEndModule) )
		::SetEvent ( m_hEvtEndModule );
	m_dwID = 0;
	printf ( "ThreadProc_SockClient end\n" );
	g_bDeleteNullSockClient = TRUE;
	return bRet;
}

BOOL CSockClient::HandleDataReceived(char *data, int size)
{
	if ( !data || size < 4 ) return FALSE;

	PACKET_TYPE *pePacketType = (PACKET_TYPE*)data;
	ASSERT ( pePacketType );
	switch ( *pePacketType )
	{
		// 要求與另一個客戶端建立直接的TCP連接
	case PACKET_TYPE_REQUEST_CONN_CLIENT:
		{
			ASSERT ( !m_bMainConn );
			ASSERT ( size == sizeof(t_ReqConnClientPkt) );
			t_ReqConnClientPkt *pReqConnClientPkt = (t_ReqConnClientPkt*)data;
			if ( !Handle_ReqConnClientPkt ( pReqConnClientPkt ) )
				return FALSE;
			break;
		}
		// 被動端(客戶端B)請求服務器斷開連接,這個時候應該將客戶端B的外部IP和端口號告訴客戶端A,并讓客戶端A主動
		// 連接客戶端B的外部IP和端口號
	case PACKET_TYPE_REQUEST_DISCONNECT:
		{
			ASSERT ( !m_bMainConn );
			ASSERT ( size == sizeof(t_ReqSrvDisconnectPkt) );
			t_ReqSrvDisconnectPkt *pReqSrvDisconnectPkt = (t_ReqSrvDisconnectPkt*)data;
			ASSERT ( pReqSrvDisconnectPkt );
			printf ( "Clinet.%u request disconnect\n", m_dwID );

			CSockClient *pSockClientHole_A = FindSocketClient ( pReqSrvDisconnectPkt->dwInviterHoleID );
			if ( !pSockClientHole_A ) return FALSE;
			pSockClientHole_A->m_SrvReqDirectConnectPkt.dwInvitedID = pReqSrvDisconnectPkt->dwInvitedID;
			STRNCPY_CS ( pSockClientHole_A->m_SrvReqDirectConnectPkt.szInvitedIP, m_csPeerAddress );
			pSockClientHole_A->m_SrvReqDirectConnectPkt.nInvitedPort = m_nPeerPort;

			Close ();

			break;
		}
		// 被動端(客戶端B)打洞和偵聽均已準備就緒
	case PACKET_TYPE_HOLE_LISTEN_READY:
		{
			ASSERT ( m_bMainConn );
			ASSERT ( size == sizeof(t_HoleListenReadyPkt) );
			t_HoleListenReadyPkt *pHoleListenReadyPkt = (t_HoleListenReadyPkt*)data;
			ASSERT ( pHoleListenReadyPkt );
			printf ( "Client.%u hole and listen ready\n", pHoleListenReadyPkt->dwInvitedID );
			// 通知正在與客戶端A通信的服務器線程,以將客戶端B的外部IP地址和端口號告訴客戶端A
			CSockClient *pSockClientHole_A = FindSocketClient ( pHoleListenReadyPkt->dwInviterHoleID );
			if ( !pSockClientHole_A ) return FALSE;
			if ( HANDLE_IS_VALID(pSockClientHole_A->m_hEvtWaitClientBHole) )
				SetEvent ( pSockClientHole_A->m_hEvtWaitClientBHole );
			break;
		}
	}

	return TRUE;
}

//
// 客戶端A請求我(服務器)協助連接客戶端B,這個包應該在打洞Socket中收到
//
BOOL CSockClient::Handle_ReqConnClientPkt(t_ReqConnClientPkt *pReqConnClientPkt)
{
	ASSERT ( !m_bMainConn );
	CSockClient *pSockClient_B = FindSocketClient ( pReqConnClientPkt->dwInvitedID );
	if ( !pSockClient_B ) return FALSE;
	printf ( "%s:%u:%u invite %s:%u:%u connection\n", m_csPeerAddress, m_nPeerPort, m_dwID,
		pSockClient_B->m_csPeerAddress, pSockClient_B->m_nPeerPort, pSockClient_B->m_dwID );

	// 客戶端A想要和客戶端B建立直接的TCP連接,服務器負責將A的外部IP和端口號告訴給B
	t_SrvReqMakeHolePkt SrvReqMakeHolePkt;
	SrvReqMakeHolePkt.dwInviterID = pReqConnClientPkt->dwInviterID;
	SrvReqMakeHolePkt.dwInviterHoleID = m_dwID;
	SrvReqMakeHolePkt.dwInvitedID = pReqConnClientPkt->dwInvitedID;
	STRNCPY_CS ( SrvReqMakeHolePkt.szClientHoleIP, m_csPeerAddress );
	SrvReqMakeHolePkt.nClientHolePort = m_nPeerPort;
	if ( pSockClient_B->SendChunk ( &SrvReqMakeHolePkt, sizeof(t_SrvReqMakeHolePkt), 0 ) != sizeof(t_SrvReqMakeHolePkt) )
		return FALSE;

	// 等待客戶端B打洞完成,完成以后通知客戶端A直接連接客戶端外部IP和端口號
	if ( !HANDLE_IS_VALID(m_hEvtWaitClientBHole) )
		return FALSE;
	if ( WaitForSingleObject ( m_hEvtWaitClientBHole, 6000*1000 ) == WAIT_OBJECT_0 )	//d
	{
		if ( SendChunk ( &m_SrvReqDirectConnectPkt, sizeof(t_SrvReqDirectConnectPkt), 0 ) == sizeof(t_SrvReqDirectConnectPkt) )
			return TRUE;
	}

	return FALSE;
}

BOOL CSockClient::SendWelcomeInfo()
{
	if ( !m_bMainConn ) return TRUE;
	t_WelcomePkt WelcomePkt;
	STRNCPY_CS ( WelcomePkt.szClientIP, m_csPeerAddress );
	WelcomePkt.nClientPort = m_nPeerPort;
	WelcomePkt.dwID = m_dwID;
	_snprintf ( WelcomePkt.szWelcomeInfo, sizeof(WelcomePkt.szWelcomeInfo),
		"Hello, ID.%u, Welcome to login", m_dwID );

	return ( SendChunk ( &WelcomePkt, sizeof(t_WelcomePkt), 0 ) == sizeof(t_WelcomePkt) );
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美激情综合五月色丁香| 亚洲国产乱码最新视频| 一区二区三区高清在线| 美女被吸乳得到大胸91| 91丨九色丨尤物| 久久久噜噜噜久久人人看| 亚洲综合精品久久| 成人va在线观看| 欧美精品一区二区三区视频| 亚洲v中文字幕| 色婷婷精品久久二区二区蜜臀av | 欧美日韩一区久久| 亚洲国产成人私人影院tom| 青青草伊人久久| 欧美高清视频www夜色资源网| 国产精品久久久久精k8| 国产美女久久久久| 欧美精品一区二区蜜臀亚洲| 全国精品久久少妇| 欧美在线短视频| 亚洲精品水蜜桃| 一本色道久久加勒比精品| 国产精品美女久久久久aⅴ| 国产中文字幕精品| 精品乱人伦一区二区三区| 秋霞午夜鲁丝一区二区老狼| 精品视频色一区| 亚洲一区成人在线| 欧美日韩一区二区三区不卡| 亚洲精品午夜久久久| 色94色欧美sute亚洲线路一ni | 亚洲国产乱码最新视频| 欧美亚洲免费在线一区| 亚洲一区二区三区精品在线| 欧美主播一区二区三区美女| 亚洲一区二区在线免费观看视频| 欧美亚洲国产一卡| 性做久久久久久久久| 日韩欧美一区中文| 激情综合五月婷婷| 国产欧美一二三区| 91网站黄www| 亚洲成人动漫精品| 精品久久久久久综合日本欧美| 久草这里只有精品视频| 国产精品色一区二区三区| 97超碰欧美中文字幕| 亚洲午夜av在线| 日韩欧美成人激情| 国产成人免费9x9x人网站视频| 国产精品乱码久久久久久| 91片黄在线观看| 亚洲成人精品一区二区| 久久综合色综合88| 99re热这里只有精品免费视频| 亚洲午夜电影在线观看| 日韩视频一区在线观看| 国产a级毛片一区| 一区二区免费视频| 久久婷婷国产综合精品青草| 成人av网站在线| 天天做天天摸天天爽国产一区| 欧美一区二区性放荡片| 东方欧美亚洲色图在线| 午夜精品久久久久久久久久| 精品国产乱码久久久久久夜甘婷婷| 成人激情免费视频| 青草国产精品久久久久久| 国产精品电影一区二区三区| 欧美日韩国产在线观看| 国产精品影视天天线| 亚洲一区二区三区不卡国产欧美 | 国产精品三级av| 欧美精品久久久久久久多人混战| 国产在线播放一区二区三区| 一区二区国产盗摄色噜噜| 久久综合狠狠综合久久综合88| 91一区二区在线| 国产精品资源站在线| 亚洲成av人影院| 国产精品第13页| 欧美精品一区二区三区蜜桃| 欧美中文字幕不卡| av中文字幕亚洲| 国产一区二区中文字幕| 亚洲成人高清在线| 亚洲欧美激情视频在线观看一区二区三区 | 国产在线乱码一区二区三区| 亚洲尤物视频在线| 亚洲人xxxx| 国产精品国产三级国产普通话99| 日韩欧美一区二区久久婷婷| 欧美日韩三级一区二区| 日本道精品一区二区三区 | 欧美欧美欧美欧美| 91社区在线播放| 成人高清视频在线观看| 国产真实乱对白精彩久久| 麻豆精品蜜桃视频网站| 视频在线观看一区二区三区| 亚洲免费观看高清完整版在线观看熊| 久久精品综合网| 2014亚洲片线观看视频免费| 精品日本一线二线三线不卡| 6080yy午夜一二三区久久| 欧美日韩一本到| 欧美日韩一区三区| 欧美日韩一本到| 91精品国产免费| 欧美精品tushy高清| 欧美一二三区精品| 日韩欧美国产一区二区在线播放| 欧美高清一级片在线| 在线不卡免费av| 日韩一区二区三区在线视频| 日韩欧美不卡一区| 2023国产精品| 欧美激情在线一区二区| 亚洲天堂av一区| 亚洲狼人国产精品| 亚洲二区视频在线| 日韩成人一级大片| 国模冰冰炮一区二区| 国产高清精品久久久久| 成人av小说网| 欧美私人免费视频| 欧美一区午夜视频在线观看| 精品入口麻豆88视频| 中文字幕+乱码+中文字幕一区| 国产精品水嫩水嫩| 一级女性全黄久久生活片免费| 亚洲一区二区五区| 精品影视av免费| 成人教育av在线| 欧美色综合天天久久综合精品| 在线成人av影院| 欧美国产丝袜视频| 午夜伊人狠狠久久| 激情深爱一区二区| 99精品视频一区| 日韩午夜小视频| 国产精品五月天| 日韩精品电影在线观看| 国产精品原创巨作av| 欧美亚洲一区三区| 精品久久久久久久久久久久久久久 | 一本在线高清不卡dvd| 6080国产精品一区二区| 国产精品丝袜在线| 全国精品久久少妇| 91色在线porny| 亚洲精品在线观| 亚洲主播在线观看| 国产精品亚洲人在线观看| 欧美日韩在线免费视频| 国产午夜精品久久久久久免费视| 亚洲日本青草视频在线怡红院| 免费成人你懂的| 色婷婷久久综合| 久久亚洲影视婷婷| 偷拍自拍另类欧美| 色综合久久六月婷婷中文字幕| 日韩一二三区视频| 一区二区三区免费| 高清不卡一区二区| 精品国产麻豆免费人成网站| 亚洲精品国产视频| 成人激情黄色小说| 日韩精品一区二区三区swag| 午夜欧美在线一二页| 91丨porny丨首页| 国产欧美一区二区精品久导航| 免费人成在线不卡| 欧美日韩免费观看一区三区| 亚洲欧美成人一区二区三区| 粉嫩欧美一区二区三区高清影视 | 国产精品99久久久久久似苏梦涵| 欧美三级中文字| 亚洲精品国产精品乱码不99| 国产mv日韩mv欧美| 国产亚洲欧美日韩日本| 看电影不卡的网站| 欧美久久久久久久久| 亚洲国产综合在线| 日本黄色一区二区| 亚洲色图在线视频| 99精品欧美一区二区三区综合在线| 久久亚洲免费视频| 国产在线一区二区| 亚洲小少妇裸体bbw| 蜜桃av一区二区三区电影| 亚洲主播在线播放| 色先锋久久av资源部| 亚洲日本一区二区| 色婷婷精品久久二区二区蜜臂av | 国产欧美一区二区三区沐欲| 精品一区在线看| 久久综合网色—综合色88| 极品美女销魂一区二区三区免费| 欧美一区二区黄色|