⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iocpsocket.cpp

📁 决战帝王1.5武神降临对喜爱决战的玩家共享研究用
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////////
// CIOCPSocket Class Define
//
#include "StdAfx.h"
#include "Iocpbase.h"
#include "IOCPSocket.h"

CIOCPSocket::CIOCPSocket()
{
	m_SockAliveFlag = 0;
	m_iWsaReadIOPendFlag = 0;
	m_iWsaWriteIOPendFlag = 0;
	m_iWsaWouldBlockFlag = 0;
	m_pIocpBase = NULL;
	m_sConnectAddress = "";
	m_rByte = 0;
	m_RecvOverlap.hEvent = NULL;
	m_SendOverlap.hEvent = NULL;
	m_nIoPendingCount = 0;
	m_Socket = INVALID_SOCKET;
	m_hSockEvent = NULL;
	m_Sid = 0;
	m_ioPendingEnableFlag = 0;

	// WSA_IO_PENDING 惑怕甫 府悸 惑怕肺 檬扁拳... 
	ResetEvent(m_SendOverlap.hEvent);

	// IKING 2002.6.29
	InitializeCriticalSection(&m_CS_CloseTime);
}

CIOCPSocket::~CIOCPSocket()
{
	if ( m_RecvOverlap.hEvent )
		CloseHandle(m_RecvOverlap.hEvent);

	if ( m_SendOverlap.hEvent )
		CloseHandle(m_SendOverlap.hEvent);

	// IKING 2002.6.29
	DeleteCriticalSection(&m_CS_CloseTime);
}

BOOL CIOCPSocket::Create( UINT nSocketPort,
						  int nSocketType, 
						  long lEvent,
						  LPCTSTR lpszSocketAddress)
{
	// 家南 积己...
	//m_Socket = socket( AF_INET, nSocketType/*SOCK_STREAM*/, 0 );
	
	m_Socket = WSASocket( AF_INET,
						  nSocketType/*SOCK_STREAM*/,
						  0,
						  NULL,
						  0,
						  WSA_FLAG_OVERLAPPED
						  );

	// 捞亥飘 汲沥...
	// IKING 2002.6.29
	if ( m_hSockEvent == NULL )
		m_hSockEvent = WSACreateEvent();

	m_SockAliveFlag = 0;

	return TRUE;
}

BOOL CIOCPSocket::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
{
	struct sockaddr_in addr;

	//m_Socket = socket(AF_INET,SOCK_STREAM,0);
	memset((void *)&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(lpszHostAddress);
	addr.sin_port = htons(nHostPort);


	int socklen, len, err;
	socklen = 1024*32;
	setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (char*)&socklen, sizeof(socklen) );
	
	len = sizeof(socklen);
	err = getsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (char*)&socklen, &len );
	if (err == SOCKET_ERROR)
	{
		TRACE("]Set Socket RecvBuf of port(%d) as %d : Fail\n", nHostPort, socklen);
		return FALSE;
	}

	socklen = 1024*32;
	setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (char*)&socklen, sizeof(socklen) );
	len = sizeof(socklen);
	err = getsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (char*)&socklen, &len );

	if (err == SOCKET_ERROR)
	{
		TRACE("]Set Socket SendBuf of port(%d) as %d : Fail\n", nHostPort, socklen);
		return FALSE;
	}
	//

	int result=connect( m_Socket,(struct sockaddr *)&addr,sizeof(addr) );

	if ( result==SOCKET_ERROR )
	{
		int err = WSAGetLastError();
		TRACE("]CONNECTION FAIL : ErrorCode[%d].\n", err);
		return FALSE;
	}

	m_sConnectAddress = lpszHostAddress;
	m_State = STATE_CONNECT;
	memcpy( &m_Addr, &addr , sizeof(addr) );

	if ( !m_pIocpBase->Associate(this) )
	{
		return FALSE;
	}

	// IKING 1999.1.
	m_RecvOverlap.hEvent = NULL;
	m_SendOverlap.hEvent = NULL;

	IOCP_RecycleRead();

	return TRUE;
}

long CIOCPSocket::IOCP_Send(char *pBuf, long length, int dwFlag)
{
	if ( m_SockAliveFlag == 1 )
		return -2;

	if ( m_iWsaWriteIOPendFlag == 1 )
	{
		// 俊矾 历厘...
		m_nIoPendingCount++;
		SetIOCPLastError( WSA_IO_PENDING );
		//return 0;
	}

	if ( m_iWsaWouldBlockFlag == 1 )
	{
		// 俊矾 历厘...
		SetIOCPLastError( WSAEWOULDBLOCK );
		return 0;
	}

	if ( length < 0 || length > SOCKET_BUF_SIZE )
	{
		return 0;
	}

	int RetValue, s_length;
	DWORD sent;
	OVERLAPPED *pOvl;

	sent = 0;
	pOvl = &m_SendOverlap;
	pOvl->Offset = OVL_SEND;
	//pOvl->OffsetHigh = length;

	char pSendBuf[SOCKET_BUF_SIZE+1];
	memcpy( pSendBuf, pBuf, length );
	//m_out.buf = m_SendBuf;
	//m_out.len = length;
	//memcpy( m_SendBuf, pBuf, length );

	s_length = length;

	do
	{
		m_out.buf = &pSendBuf[length-s_length];
		m_out.len = s_length;
		pOvl->OffsetHigh = s_length;

		RetValue = WSASend( m_Socket, &m_out, 1, &sent, dwFlag, pOvl, NULL);
		
		if ( RetValue != 0 )
		{
			int last_err;
			last_err = WSAGetLastError();

			// 俊矾 历厘...
			SetIOCPLastError(last_err);

			if ( last_err == WSA_IO_PENDING )
			{
				// WSA_IO_PENDING 眉农...
				int ret;
				DWORD transfer;
				DWORD dwFlag;

				DWORD tick_count = GetTickCount();
				do
				{
					ret = WSAGetOverlappedResult(m_Socket,
												 pOvl,
												 &transfer,
												 FALSE,
												 &dwFlag);
				} while( ret == FALSE && (GetTickCount() - tick_count) < 5 );

				if ( ret == TRUE )
				{
					TRACE("]SEND : WSA_IO_PENDING BUT ADJUST TO CONTINUE[SID=%d, C=%d]\n", m_Sid, m_nIoPendingCount);
					RetValue = transfer;
				}
				else
				{
					m_nIoPendingCount++;
					m_SockAliveFlag = 1;
					RetValue = -2;
					m_iWsaWriteIOPendFlag = 1;

					TRACE("]SEND : WSA_IO_PENDING[SID=%d, C=%d]\n", m_Sid, m_nIoPendingCount);
				}
				//
				/*
				m_nIoPendingCount++;

				TRACE("]SEND : WSA_IO_PENDING[SID=%d, C=%d]\n", m_Sid, m_nIoPendingCount);

				m_iWsaWriteIOPendFlag = 1;
				sent = length;

				// IKING 2001.1.
				if ( m_ioPendingEnableFlag == 0 )
				{
					m_SockAliveFlag = 1;
					RetValue = -2;
				}
				else //辑滚埃狼 荤侩登绰 家南老 版快...
				{
					RetValue = 0;
				}
				*/

				return RetValue;
				//
			}
			else if ( last_err == WSAEWOULDBLOCK )
			{
				TRACE("]SEND : WSAEWOULDBLOCK\n");

				m_iWsaWouldBlockFlag = 1;
				return RetValue;
			}
			else
			{
				TRACE("]SEND : Error In Sending[%d] = %d\n", m_Sid, last_err);

				m_SockAliveFlag = 1;
				RetValue = -2;
				return RetValue;
			}
		}
		s_length -= sent;

	} while ( s_length > 0 );

	return sent;
}

void CIOCPSocket::IOCP_OnSend(int nErrorCode)
{
	m_iWsaWriteIOPendFlag = 0;
	m_iWsaWouldBlockFlag = 0;
}

int CIOCPSocket::IOCP_RecycleRead()
{
	if ( m_SockAliveFlag != 0 )
	{
		TRACE("]SOCKET IS DEAD[%d]...\n", m_Sid);
		return -2;
	}

	int RetValue;
	DWORD insize, dwFlag=0;
	OVERLAPPED *pOvl;

	memset(m_RecvBuf, NULL, MAX_RECV_BUFF_SIZE );
	m_in.len = MAX_RECV_BUFF_SIZE;
	m_in.buf = m_RecvBuf;

	pOvl = &m_RecvOverlap;
	pOvl->Offset = OVL_RECEIVE;

	RetValue = WSARecv( m_Socket, &m_in, 1, &insize, &dwFlag, pOvl, NULL );

 	if ( RetValue == SOCKET_ERROR )
	{
		int last_err;
		last_err = WSAGetLastError();

		// 俊矾 历厘...
		SetIOCPLastError(last_err);

		if ( last_err == WSA_IO_PENDING )
		{
			//TRACE("RECV : WSA_IO_PENDING=%d.\n", last_err);
			m_iWsaReadIOPendFlag = 1;
			return 0;
		}
		else if ( last_err == WSAEWOULDBLOCK )
		{
			//TRACE("]RECV[%d] : WSAEWOULDBLOCK=%d.\n", m_Sid, last_err);
			return 0;
		}
		else
		{
			TRACE("]RECV[%d] : ERROR CODE = %d\n", m_Sid, last_err);
			m_SockAliveFlag = 1;

			return -1;
		}
	}

	m_iWsaReadIOPendFlag = 0;

	return RetValue;
}

void CIOCPSocket::Receive(int rBytes)
{
	if ( m_SockAliveFlag != 0 )
		return;

	int RetValue;
	//WSABUF in;
	DWORD insize, dwFlag=0;
	OVERLAPPED *pOvl;

	memset(m_RecvBuf, NULL, MAX_RECV_BUFF_SIZE );

	m_in.len = MAX_RECV_BUFF_SIZE;
	m_in.buf = m_RecvBuf;

	pOvl = &m_RecvOverlap;
	pOvl->Offset = OVL_RECEIVE;

	RetValue = WSARecv( m_Socket, &m_in, 1, &insize, &dwFlag, pOvl, NULL );	// Completion Port俊 Associate等 Socket俊 滚欺甫 扒促

 	if ( RetValue == SOCKET_ERROR )
	{
		int last_err;
		last_err = WSAGetLastError();

		// 俊矾 历厘...
		SetIOCPLastError(last_err);

		if ( last_err == WSA_IO_PENDING )
		{
			TRACE("]RECV : WSA_IO_PENDING=%d.\n", last_err);

			m_iWsaReadIOPendFlag = 1;
			return;
		}
		else if ( last_err == WSAEWOULDBLOCK )
		{
			//TRACE("]RECV : WSAEWOULDBLOCK=%d.\n", last_err);
			return;
		}
		else
		{
			TRACE("]RECV : ERROR CODE = %d\n", last_err);
			m_SockAliveFlag = 1;
		}
	}
}

BOOL CIOCPSocket::AsyncSelect( long lEvent )
{
	int retEventResult;

	retEventResult = WSAEventSelect( m_Socket, m_hSockEvent, lEvent );

	return ( !retEventResult );
}

BOOL CIOCPSocket::SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel )
{
	int retValue;
	retValue = setsockopt( m_Socket, nLevel, nOptionName, (char *)lpOptionValue, nOptionLen );

	return ( !retValue );
}

BOOL CIOCPSocket::ShutDown( int nHow )
{
	int retValue;
	retValue = shutdown( m_Socket, nHow );

	return ( !retValue );
}

void CIOCPSocket::IOCP_OnClose( int nErrorCode )
{
	if ( m_Socket != INVALID_SOCKET )
	{
		closesocket( m_Socket );
		m_Socket = INVALID_SOCKET;
	}
}

void CIOCPSocket::IOCP_Close()
{
	// 家南俊 茄锅 Close 脚龋甫 焊陈栏搁 促矫 焊郴瘤 给窍霸...
	if ( m_SockAliveFlag == -1 ) return;

	// IKING 2002.6.29
	EnterCriticalSection(&m_CS_CloseTime);
	if ( m_SockAliveFlag == -1 )
	{
		LeaveCriticalSection(&m_CS_CloseTime);
		return;
	}
	// 家南阑 磷篮 惑怕肺...
	m_SockAliveFlag = -1;
	LeaveCriticalSection(&m_CS_CloseTime);

	if ( m_Socket != INVALID_SOCKET )
	{
		closesocket(m_Socket);
		m_Socket = INVALID_SOCKET;
	}

/*	if ( m_hSockEvent )
	{
		WSACloseEvent( m_hSockEvent );
		m_hSockEvent = NULL;
	}

	if ( m_RecvOverlap.hEvent )
	{
		CloseHandle(m_RecvOverlap.hEvent);
		m_RecvOverlap.hEvent = NULL;
	}

	if ( m_SendOverlap.hEvent )
	{
		CloseHandle(m_SendOverlap.hEvent);
		m_SendOverlap.hEvent = NULL;
	}
*/
}

void CIOCPSocket::StopAction()
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -