bool MightyTCPCompletionPortServer::SendData(const char *pData, int nLen, const string & strLinkNo)
{
	
	PCompletionPortIOObject sendHandle=NULL;
	
	PCompletionPort_BufObj pSendBufRole=NULL;


	//map<string,PCompletionPortIOObject>::iterator leftPos,rightPos;
	//leftPos=m_ActiveSocketMap.begin();
	//rightPos=m_ActiveSocketMap.end();
	sendHandle=SearchSocketObj(strLinkNo);

	if (sendHandle!=NULL)
	{

		pSendBufRole=AllocateBuffer(sendHandle,nLen);
		if (pSendBufRole)
		{
			pSendBufRole->nLen = nLen;
			memcpy(pSendBufRole->buff,pData, nLen);
			PostSend(pSendBufRole);
			return true;
		}
	}

	return false;
}
bool IocpTransmitStrategy::HandleSendSuccess(const IocpOperation* iocpOperation
    , DWORD byteNumber) {
    MZ_ASSERT_TRUE(&m_sendOperation == iocpOperation);

    auto& socketBuffer = m_transmitSocket.TheSocketBuffer();
    
    const auto planLength = socketBuffer.m_sendPlan.GetCurLength();
    const auto cacheLength = socketBuffer.m_sendCache.GetCurLength();
    //NS_SHARE::Log(MZ_LOG_DEBUG, "Socket Send: plan[%d] cache[%d]. [%s:%d]\n", planLength, cacheLength, __FILE__, __LINE__);

    if (byteNumber == 0) {
        NS_SHARE::Log(MZ_LOG_DEBUG, "Socket Info: socket close. [%s:%d]\n", __FILE__, __LINE__);
        m_transmitSocket.Close();
        return true;
    }

    const auto sendData = nullptr;
    const auto sendLength = byteNumber;

    m_transmitSocket.OnSended(sendData, sendLength);

    const auto restLength = socketBuffer.PreserveSendPlan(byteNumber);
    MZ_UNUSED_VARIABLE(restLength);

    return PostSend();
}
Beispiel #3
0
int CNTReader::SendCommand(const byte *sbuff,short slen,unsigned char * rbuff,short *rlen,int timeout)
{
    unsigned char sCmd[512]= {0},sResp[512]= {0};
    int  nCmdLen=0;
    if(!IsOpen())
        return PORT_NOTOPEN_ERROR;
    sCmd[0]=0x02;
    sCmd[1]=slen/256;
    sCmd[2]=slen%256;
    memcpy(sCmd+3,sbuff,slen);
    nCmdLen=3+slen;
    sCmd[nCmdLen]=XOR(sbuff,slen);
    nCmdLen++;
    sCmd[nCmdLen]=0x03;
    nCmdLen++;
    if( !PostSend(sCmd,nCmdLen,timeout))
    {
        return SEND_DATA_ERROR;
    }
    //Sleep(80);
    if( !PostRecv(sResp,sizeof(sResp),timeout))
    {
        return RECV_DATA_ERROR;
    }
//Resp:数据长度(2字节)+状态码(2字节)+数据
    *rlen=sResp[0]*256+sResp[1]-2;	//去掉2字节状态码
    if(*rlen>256)
        *rlen=256;
    if(*rlen>0) memcpy(rbuff,sResp+4,*rlen);
    return sResp[2]*256+sResp[3];
}
Beispiel #4
0
void EasyIocp::PushToDebug(CompTransmitKey *transKey)
{
	sockaddr_in serverAddr, clientAddr;
	char data[EASYIOCP_MAX_BUFF];
	const char *operType;
	DWORD len;

	transKey->GetBothAddr(&serverAddr, &clientAddr);

	EasyIocpBuffer *iocpBuffer = transKey->GetBuffer();
	len = iocpBuffer->GetBody(data, EASYIOCP_MAX_BUFF);
	data[len] = 0;

	if(transKey->GetOperType() == operRecv) {
		operType = "recv";

		print("%s:%d %s from %s:%d, data: %s", 
			inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port), operType,
			inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port), data);

		PostSend(transKey->GetSocket(), data, len);
	}
	else if(transKey->GetOperType() == operSend) {
		/*operType = "send";
		print("%s:%d %s to %s:%d, data:%s", 
			inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port), operType,
			inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port), data);*/

		PostRecv(transKey);
	}
	else {
		print("EasyIocp::PushToDebug: invalid oper.");
	}
}
Beispiel #5
0
BOOL CIOCPServer::SendText(CIOCPContext *pContext, char *pszText, int nLen)
{
	CIOCPBuffer *pBuffer = AllocateBuffer(nLen);
	if(pBuffer != NULL)
	{
		memcpy(pBuffer->buff, pszText, nLen);
		return PostSend(pContext, pBuffer);
	}
	return FALSE;
}
Beispiel #6
0
///函数:投递一个send请求。
bool 
EasyIocp::PostSend(SOCKET transSock, char *data, int len)
{
	CompTransmitKey *transKey = easyClients_.FindClient(transSock);
	if(!transKey)
		return false;

	EasyIocpBuffer *iocpBuffer = transKey->GetBuffer();
	iocpBuffer->SetBody(data, len);

	return PostSend(transKey);
}
Beispiel #7
0
BOOL CIOCPServer::SendText(CIOCPContext *pContext, char *pszText, int nLen)
{
	CIOCPBuffer *pBuffer = AllocateBuffer(nLen);
	if(pBuffer != NULL)
	{
		memcpy(pBuffer->buff, pszText, nLen);
		if (PostSend(pContext, pBuffer))
			return true;
  	    ReleaseBuffer(pBuffer);
	}
	return false;
}
void Session::EchoBack()
{
	size_t len = mRecvBuffer.GetContiguiousBytes();

	if (len == 0)
		return;

	if (false == PostSend(mRecvBuffer.GetBufferStart(), len))
		return;

	mRecvBuffer.Remove(len);

}
Beispiel #9
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief 
/// \param CAsyncTimerEvent * evt 
/// \return void
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CAsyncPlayer::OnTimer(CAsyncTimerEvent* evt)
{
	SafeGuard();

	if (m_PingTimer == evt)
	{
		CPacketWriter<PKTEcho> echoPacket;
		echoPacket->SetStr(_T("Ping"));
		PostSend(echoPacket);

		TRACE(_T("Ping send"));
	}
}
Beispiel #10
0
void 
EasyIocp::DoSend(CompTransmitKey *transKey, DWORD transBytes)
{
	EasyIocpBuffer *iocpBuffer = transKey->GetBuffer();

	iocpBuffer->AddTransBytes(transBytes);
	if(iocpBuffer->IsTransComplete()) {
		//数据发送完毕
		//PushToBusiness(transKey);
		PushToDebug(transKey);
	}else {
		PostSend(transKey);	//数据未发送完毕,则继续发送
	}
}
Beispiel #11
0
bool Session::SendRequest(BasePacket* pPacket)
{
    IPacketProtocol* pProtocol = GetPacketProtocol();
    if (NULL == pProtocol)
        return false;

    char* pBuffer = NULL;
    int bufferSize;
    if (false == pProtocol->Encode(pPacket, &pBuffer, bufferSize))
        return false;

    PostSend(false, bufferSize, pBuffer);

    return true;
}
bool IocpTransmitStrategy::PostOutput() {
    if (!m_transmitSocket.IsWorking()) {
        return false;
    }

    if (m_sendOperation.IsBusy()) {
        return true;
    }

    if (!m_transmitSocket.TheSocketBuffer().HasDataToSend()) {
        return true;
    }

    m_sendOperation.SetBusy(true);

    return PostSend();
}
Beispiel #13
0
void NetSocket::PrepareSend()
{
    unsigned int sendPacketSize = 0;
    MemoryBlock* buffer = nullptr;

    while (!_sendPendingQueue.empty()
        && (_sendQueue.unsafe_size() < MAX_SEND_ARRAY_SIZE)
        && (sendPacketSize < DEF_SOCKET_BUFFER_SIZE))
    {
        _sendPendingQueue.try_pop(buffer);
        _sendQueue.push(buffer);

        sendPacketSize += buffer->GetDataLen();
    }

    if (sendPacketSize > 0)
        PostSend();
}
Beispiel #14
0
void Server::Echo(Packet* packet)
{
    assert(packet);
    assert(packet->GetSender());

    CritSecLock lock(m_CSForClients);

    ClientList::iterator itor = std::find(m_Clients.begin(), m_Clients.end(), packet->GetSender());

    if (itor == m_Clients.end())
    {
        // No client to send it back.
        Packet::Destroy(packet);
    }
    else
    {
        PostSend(packet->GetSender(), packet);
    }
}
Beispiel #15
0
void Session::handle_write(const boost::system::error_code& error, size_t bytes_transferred)
{
    delete[] m_SendDataQueue.front();
    m_SendDataQueue.pop_front();

    m_SendDataSizeQueue.pop_front();

    if( m_SendDataQueue.empty() == false )
    {
        m_bCompletedWrite = false;

        char* pData = m_SendDataQueue.front();

        int nSize = m_SendDataSizeQueue.front();

        PostSend(true, nSize, pData);
    }
    else
    {
        m_bCompletedWrite = true;
    }
}
//接数数据
int  CYCTReaderInterface::SendReaderCommand(char *ComPort,unsigned char Cmd,unsigned char *SendData,
											unsigned  char SendDataLen,unsigned char *RetCode,
											unsigned char *RecvData,unsigned char* RecvDataLen)
{
	char sCmd[256],sResp[256];
	int  nCmdLen=0;

	memset(sCmd,0,sizeof sCmd);
	memset(sResp,0,sizeof sResp);
	if( !m_bComStatus )
	{
		if( !CPU_Open(m_sCom,57600) )
		{
			RetCode[0]=0x4F;
			return 1;
		}
	}
	sCmd[0]=(char)0xBA;
	sCmd[1]=(char)(2+SendDataLen);
	sCmd[2]=Cmd;
	memcpy(sCmd+3,SendData,SendDataLen);
	nCmdLen=3+SendDataLen;
	sCmd[nCmdLen]=XOR((byte*)sCmd,nCmdLen);
	nCmdLen++;
	if( !PostSend(sCmd,nCmdLen,2000) )
	{
		return SEND_DATA_ERROR;
	}
	Sleep(80);
	if( !PostRecv(sResp,sizeof(sResp),2000) )
	{
		return RECV_DATA_ERROR;
	}
	*RetCode=sResp[3];
	*RecvDataLen=sResp[1]-3;	
	if(*RecvDataLen>0) memcpy(RecvData,sResp+4,*RecvDataLen);	
	return 0;
}
BOOL HandleIO(PBUFFER_OBJ pBuffer)
{
    PSOCKET_OBJ pSocket = pBuffer->pSocket; // 从BUFFER_OBJ对象中提取SOCKET_OBJ对象指针,为的是方便引用
    pSocket->nOutstandingOps --;

    DWORD dwTrans;   //用于取得实际传输字节的数量
    DWORD dwFlags;   //用于取得完成状态
    // 获取重叠操作结果 true 重叠操作成功  false 套接字上有错误发生
    BOOL bRet = ::WSAGetOverlappedResult(pSocket->s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags);
    if(!bRet)
    {
        // 在此套节字上有错误发生,因此,关闭套节字,移除此缓冲区对象。
        // 如果没有其它抛出的I/O请求了,释放此缓冲区对象,否则,等待此套节字上的其它I/O也完成
        if(pSocket->s != INVALID_SOCKET)
        {
            ::closesocket(pSocket->s);
            pSocket->s = INVALID_SOCKET;
        }

        if(pSocket->nOutstandingOps == 0)
            FreeSocketObj(pSocket);

        FreeBufferObj(pBuffer);
        return FALSE;
    }

    // 没有错误发生,处理已完成的I/O
    switch(pBuffer->nOperation)
    {
    case OP_ACCEPT:	// 接收到一个新的连接,并接收到了对方发来的第一个封包
    {
        // 为新客户创建一个SOCKET_OBJ对象
        PSOCKET_OBJ pClient = GetSocketObj(pBuffer->sAccept);

        // 为收发数据创建一个BUFFER_OBJ对象,这个对象会在套节字出错或者关闭时释放
        PBUFFER_OBJ pSend = GetBufferObj(pClient, BUFFER_SIZE);
        if(pSend == NULL)
        {
            printf(" Too much connections! \n");
            FreeSocketObj(pClient);
            return FALSE;
        }

        SOCKADDR_IN LocalSockAddr;
        SOCKADDR_IN RemoteSockAddr;
        int nLocalLen, nRmoteLen;
        LPSOCKADDR pLocalAddr, pRemoteAddr;
        g_pfnGetAcceptExSockaddrs(
            pBuffer->buff,
            pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2),
            sizeof(sockaddr_in) + 16,
            sizeof(sockaddr_in) + 16,
            (SOCKADDR **)&pLocalAddr,
            &nLocalLen,
            (SOCKADDR **)&pRemoteAddr,
            &nRmoteLen);

        memcpy(&LocalSockAddr, pLocalAddr, nLocalLen);
        memcpy(&RemoteSockAddr, pRemoteAddr, nRmoteLen);
        printf("Local Accepted client:%s:%d\n", inet_ntoa(LocalSockAddr.sin_addr), ntohs(LocalSockAddr.sin_port));
        printf("Remote Accepted client:%s:%d\n", inet_ntoa(RemoteSockAddr.sin_addr), ntohs(RemoteSockAddr.sin_port));

        RebuildArray();

        // 将数据复制到发送缓冲区
        pSend->nLen = dwTrans;
        memcpy(pSend->buff, pBuffer->buff, dwTrans);

        // 投递此发送I/O(将数据回显给客户)
        if(!PostSend(pSend))
        {
            // 万一出错的话,释放上面刚申请的两个对象
            FreeSocketObj(pSocket);
            FreeBufferObj(pSend);
            return FALSE;
        }
        // 继续投递接受I/O
        PostAccept(pBuffer);
    }
    break;
    case OP_RECV:	// 接收数据完成
    {
        if(dwTrans > 0)
        {
            // 创建一个缓冲区,以发送数据。这里就使用原来的缓冲区
            PBUFFER_OBJ pSend = pBuffer;
            printf("收到:%s\r\n", pBuffer->buff);
            pSend->nLen = dwTrans;

            // 投递发送I/O(将数据回显给客户)
            PostSend(pSend);
        }
        else	// 套节字关闭
        {

            // 必须先关闭套节字,以便在此套节字上投递的其它I/O也返回
            if(pSocket->s != INVALID_SOCKET)
            {
                ::closesocket(pSocket->s);
                pSocket->s = INVALID_SOCKET;
            }

            if(pSocket->nOutstandingOps == 0)
                FreeSocketObj(pSocket);

            FreeBufferObj(pBuffer);
            return FALSE;
        }
    }
    break;
    case OP_SEND:		// 发送数据完成
    {
        if(dwTrans > 0)
        {
            // 继续使用这个缓冲区投递接收数据的请求
            pBuffer->nLen = BUFFER_SIZE;
            PostRecv(pBuffer);
        }
        else	// 套节字关闭
        {
            // 同样,要先关闭套节字
            if(pSocket->s != INVALID_SOCKET)
            {
                ::closesocket(pSocket->s);
                pSocket->s = INVALID_SOCKET;
            }

            if(pSocket->nOutstandingOps == 0)
                FreeSocketObj(pSocket);

            FreeBufferObj(pBuffer);
            return FALSE;
        }
    }
    break;
    }
    return TRUE;
}
Beispiel #18
0
int Connections::PushPacket(Packet* pPacket)
{
    FUNCTION_BEGIN();

    if (false == IsStatus(CONNSTATUS_ACTIVE))
    {
        return 1;//ERR_NET_CONNECTION_STATUS_WRONG
    }


    if (false == pPacket->IsValidPacket())
    {
        return 2;//ERR_NET_PACKET_INVALID
    }

    _mutexSend.Lock();

    if (pPacket->GetPacketLen() > GetMaxSendPacketSize())
    {
        _mutexSend.Unlock();
        return 3;//ERR_NET_PACKET_EXCEED_ALLOWED_SIZE
    }


    if (_sendBuffer.GetPushAvailableSize() <= pPacket->GetUsedSize())
    {
        if (false == IsSetControlFlag(CONTROL_FLAG_USE_SEND_QUEUE))
        {
            _mutexSend.Unlock();
            return 4;//ERR_NET_SESSION_SEND_BUFFER_OVERFLOW
        }
        else
        {
            Packet * QueuedPacket = new Packet(*pPacket);
            if (NULL == QueuedPacket)
            {
                _mutexSend.Unlock();
                return 5;//ERR_SYS_MEMORY_ALLOC_FAIL
            }

            if (false == _sendQueue.PushPacket(QueuedPacket))
            {
                SAFE_DELETE(QueuedPacket);

                _mutexSend.Unlock();
                return 6;//ERR_NET_SESSION_SEND_BUFFER_OVERFLOW;
            }

            _mutexSend.Unlock();
            return 0;
        }
    }

    memcpy(_sendBuffer.GetQueuePushPtr(), pPacket->GetPacketBuffer(), pPacket->GetUsedSize());

    Packet sendPacket(_sendBuffer.GetQueuePushPtr());
    BYTE Sequence = (BYTE)(_PacketSendCount & PACKET_MAX_SEQUENCE);
    SetSequence(sendPacket.GetPacketHeader(), Sequence);

    int rc = 0;

    if (_PacketEncoder)
    {
        rc = _PacketEncoder->TxEncrypt(sendPacket);
        if (0 != rc)
        {
            _mutexSend.Unlock();
            return 7;//ERR_NET_PACKET_ENCRYPT_FAIL
        }
    }

    _sendBuffer.IncreasePushPos(pPacket->GetUsedSize());
    IncreasePacketSend();

    if (false == _IsSending)
    {
        rc = PostSend();
        if (0 != rc)
        {
            _mutexSend.Unlock();
            return rc;
        }

        _IsSending = true;
    }

    _mutexSend.Unlock();

    return 0;
}
Beispiel #19
0
int Connections::CompleteSend(DWORD TransferedBytes)
{
    UNREFERENCED_PARAMETER(TransferedBytes);

    FUNCTION_BEGIN();


    IncreaseBytesSend(TransferedBytes);


    _mutexSend.Lock();
    _sendBuffer.IncreasePopPos(TransferedBytes);

    int rc = 0;
    if (IsSetControlFlag(CONTROL_FLAG_USE_SEND_QUEUE))
    {
        Packet * SendPacket = _sendQueue.PeekPacket();
        while (SendPacket)
        {
            if (_sendBuffer.GetPushAvailableSize() <= SendPacket->GetUsedSize())
            {
                break;
            }

            BYTE Sequence = (BYTE)(_PacketSendCount & PACKET_MAX_SEQUENCE);
            SetSequence(SendPacket->GetPacketHeader(), Sequence);

            if (_PacketEncoder)
            {
                rc = _PacketEncoder->TxEncrypt(*SendPacket);
                if (0 != rc)
                {
                    _mutexSend.Unlock();

                    Logger::Log("Session[%X] TxEncrypt Error[%d]\n", this, rc);
                    return 1; //ERR_NET_PACKET_ENCRYPT_FAIL
                }
            }

            memcpy(_sendBuffer.GetQueuePushPtr(), SendPacket->GetPacketBuffer(), SendPacket->GetUsedSize());
            _sendBuffer.IncreasePushPos(SendPacket->GetUsedSize());
            IncreasePacketSend();

            _sendQueue.PopPacket();
            SAFE_DELETE(SendPacket);

            SendPacket = _sendQueue.PeekPacket();
        }
    }


    if (_sendBuffer.GetCurSize())
    {
        rc = PostSend();
        if (0 != rc)
        {
            _IsSending = false;
            _mutexSend.Unlock();
            Disconnect(false);

            Logger::Log("Session[%X] PostSend Error[%d]\n", this, rc);
            return 0;
        }
    }
    else
    {
        _IsSending = false;
    }


    _mutexSend.Unlock();

    return 0;
}
Beispiel #20
0
//---------------------------------------------------------------------------------------------------------------------------
//HanelIO()
//---------------------------------------------------------------------------------------------------------------------------
void CIocpServer::HandleIo(SOCKET_OBJ *sock, BUFFER_OBJ *buf, 
						   HANDLE CompPort, DWORD BytesTransfered, DWORD error,
						   ADOConn *pAdo,bool isClient)
{

#ifdef LOG_STATUS
	InterlockedDecrement(&gIoCount);
#endif

	switch(buf->operation) 
	{	
	case OP_ACCEPT:		//处理AcceptEx的返回	
		LOCK(&sock->cs);//加锁
		{
			if(error == 0)
			{			
				SOCKET_OBJ *clientobj = GetSocketObj(buf->sclient);//创建一个客户端sockobj
				HANDLE hrc = CreateIoCompletionPort(	           //将sockobj添加到完成端口处理列表	
					(HANDLE)buf->sclient,
					CompPort,
					(ULONG_PTR)clientobj,
					0
					);

				if (hrc != NULL) 
				{
					//读取ip地址
					SOCKADDR *local=NULL;
					SOCKADDR *remote=NULL;
					int local_len;
					int remote_len;

					lpfnGetAcceptExSockaddrs(buf->buf,0,sizeof(SOCKADDR_STORAGE) + 16
						,sizeof(SOCKADDR_STORAGE) + 16,
						&local,&local_len,&remote,&remote_len);
					clientobj->addr = ((SOCKADDR_IN *)remote)->sin_addr;

#ifdef LOG_LEVEL1
					Log_Server.Write("--新连接 ip = %s , sock = %d ",GetAddress(clientobj),
						clientobj->s);
#endif

					BUFFER_OBJ *recvobj = GetBufferObj();
//禁用发送缓冲
#ifdef SEND_BUF_DISABLE
					BOOL sndbuf=0;
					setsockopt(buf->sclient,SOL_SOCKET,SO_SNDBUF,(char *)&sndbuf,sizeof(sndbuf));
#endif
					LOCK(&clientobj->cs);

					if(PostRecv(clientobj,recvobj) == 0)
					{ 
#ifdef DEBUG_IOCP
						clientobj->sockfd = clientobj->s;
						recvobj->sclient = clientobj->s;
#endif
						clientobj->recvobj = recvobj;
						AddAlive(clientobj,GetTickCount()); //把他添加到心跳列表,如果一个客户端连上来以后不发数据,会被踢掉
					}
					else
					{
						FreeBufferObj(recvobj);
						closesocket(clientobj->s);     //注意关闭句柄,clientobj->s的句柄在PostAccept时候创建
						clientobj->s = INVALID_SOCKET;
						FreeSocketObj(clientobj);
					}

					UNLOCK(&clientobj->cs);
				} 
				else
				{	//创建完成端口失败,像new失败一样,基本上不会出现
#ifdef LOG_LEVEL2
					Log_Server.Write("CreateIoCompletionPort 错误:%d",GetLastError());
#endif
					closesocket(clientobj->s);
					clientobj->s = INVALID_SOCKET;
					FreeSocketObj(clientobj);
				}
			}
			else	//如果AcceptEx返回出错,说明有一个客户端连了一半就退了,需要把他的句柄关了.
				closesocket(buf->sclient);

			InterlockedDecrement(&m_accept_count);
			// 一般情况下重新PostAccept
			if(m_accept_count < DEFAULT_ACCEPTEX_COUNT *2)
			{
				if(PostAccept(sock,buf)!=0)
					FreeBufferObj(buf);
			}
		}

		UNLOCK(&sock->cs);
		break;
	case OP_READ: //收到数据了
		{
			LOCK(&sock->cs); //锁一下

			bool bflag = false;
			_ASSERTE(buf == sock->recvobj);

			if(error == 0 && BytesTransfered > 0 )
			{ 
#ifdef LOG_LEVEL1  
				char head[256];
				sprintf(head,"(%d) :接收",sock->s);
				if(isClient)
					strcat(head,"CL");
				Log_Server.WriteHex(buf->buf+buf->buflen,BytesTransfered,head,(int)strlen(head));
#endif

				buf->buflen += BytesTransfered; 
				int nret = 0; 

				if(isClient)
				{	//调用可以重载的虚函数
					//开锁,否则在On系列函数中调用Send(),CloseSock()时候会死锁!
					UNLOCK(&sock->cs);
					nret = CLOnRead(sock,buf->buf,buf->buflen,sock->flag,pAdo);
					LOCK(&sock->cs);
				}
				else if(sock->flag_accept == 1)	
				{
					UNLOCK(&sock->cs);
					nret = OnRead(sock,buf->buf,buf->buflen,pAdo);
					LOCK(&sock->cs);
				}
				else
				{
					sock->flag_close = 1;  //设置允许标志,否则调用Send将会失败
					sock->flag_accept = 1; //设置accept标志
#ifndef ENABLE_KEEPALIVE		//没有启用KeepAlive	
					DeleteAlive(sock);
#endif
#ifdef DEBUG_IOCP
					sock->freeed = 0;
					sock->onclosed = 0;
#endif
					UNLOCK(&sock->cs);
					nret = OnAccept(sock,buf->buf,buf->buflen,pAdo);
					LOCK(&sock->cs);
				}

				_ASSERTE(nret >= 0 && nret <= buf->buflen);
				if(nret < 0 || nret > buf->buflen)
				{
#ifdef LOG_LEVEL2
					Log_Server.Write("指令处理出错啦\n");
					nret = buf->buflen; //强制设置为完全处理
#endif 
				}

#ifdef ENABLE_KEEPALIVE
				sock->timeAlive = GetTickCount(); //设置新的心跳时间
#endif
				buf->buflen -= nret;
				if(nret > 0 && buf->buflen > 0)
					memmove(buf->buf,buf->buf+nret,buf->buflen);

				if(PostRecv(sock,buf) == 0) //重新递交一个接收操作
					bflag = true;
			}

			if(!bflag)	
			{
				DeleteClose(sock); //看看是否存在于延时关闭列表中
				DeleteAlive(sock); //看看是否存在于心跳列表中

				if(sock->s != INVALID_SOCKET) {
					closesocket(sock->s);
					sock->s = INVALID_SOCKET;
				}

				sock->flag_close = 0; //设置关闭标志

				FreeBufferObj(buf);

				if( sock->flag_accept == 1) 
				{
					UNLOCK(&sock->cs);

					if(!isClient)
						OnClose(sock,pAdo); //调用一次OnClose(),告诉上层的程序,不要再去用这个sock了
					else
						CLOnClose(sock,sock->flag,pAdo);

					LOCK(&sock->cs);
#ifdef DEBUG_IOCP
					sock->onclosed = 1; //调试时设置关闭标志,用于检测是否存在逻辑问题
#endif
				}

				sock->recvobj = NULL;
				if(sock->recvobj == NULL && sock->sendobj == NULL) 
				{
					UNLOCK(&sock->cs);
					FreeSocketObj(sock); //释放该客户端对应的sockobj对象
					return;
				}
			}

			UNLOCK(&sock->cs);
		}
		break;
	case OP_WRITE:
		LOCK(&sock->cs);
		{
			_ASSERTE(buf == sock->sendobj);
			bool bflag = false;
			BUFFER_OBJ *tmpobj = sock->sendobj;
			sock->sendobj = sock->sendobj->next;

			if(error == 0 && BytesTransfered > 0) //前一个发送已经完成
			{ 
#ifdef LOG_LEVEL1
				char head[256];
				sprintf(head,"(%d) :发送",sock->s);
				if(isClient)
					strcat(head,"CL");
				Log_Server.WriteHex(buf->buf,BytesTransfered,head,(int)strlen(head));
#endif

				//检查发送队列
				if(sock->sendobj == NULL)
					bflag = true;
				else if(PostSend(sock,sock->sendobj) == 0) 
					bflag = true;				
			}

			FreeBufferObj(tmpobj);

			if(!bflag)
			{
				sock->flag_close = 0; //设置关闭标志
				while(sock->sendobj)
				{
					tmpobj = sock->sendobj;
					sock->sendobj = sock->sendobj->next;
					FreeBufferObj(tmpobj); 
				}

				if(sock->recvobj == NULL && sock->sendobj == NULL)
				{
					UNLOCK(&sock->cs);
					FreeSocketObj(sock); //如果OP_READ时,sock->sendobj!=NULL,那么需要在这里释放客户端的SocketOBJ
					return;
				}
			}
		}

		UNLOCK(&sock->cs);
		break;
	}

}
Beispiel #21
0
//如果发送队列存在,Send()首先尝试将数据添加到队列的最后一个BufferOBJ.如果BufferOBJ的可用空间不足,
//Send()将开辟一个新的BufferOBJ用于发送.当发送队列为空时,Send()将调用PostSend()立即提交一个发送操作
//
int CIocpServer::Send(SOCKET_OBJ *sock,const void * buffer,int len)//发送向客户端数据
{
	_ASSERTE(len <= DEFAULT_BUFFER_SIZE*MAX_UNSENDS_COUNT && len > 0);

	if(sock == NULL || len > DEFAULT_BUFFER_SIZE*MAX_UNSENDS_COUNT || len <= 0)
		return -1;

	BUFFER_OBJ * tmpbuf;
	int rc=NO_ERROR;

#ifdef DEBUG_IOCP
	_ASSERTE(sock->onclosed == 0); //已经调用过OnClose()还发?
	_ASSERTE(sock->freeed == 0);   //已经free掉了!
#endif

	InterlockedIncrement(&sock->sending_count); //为了安全的freeobj

	if( ( sock->flag_close == 0 ) || (sock->s == INVALID_SOCKET) )
	{
		InterlockedDecrement(&sock->sending_count);
		return -1;
	}

	int i=0;
	int len2=len;
	char *buf2;

	if(len2 > DEFAULT_BUFFER_SIZE)
		len2 = DEFAULT_BUFFER_SIZE;

	LOCK(&sock->cs);

	tmpbuf = sock->sendobj;
	if(tmpbuf == NULL)
	{ //发送队列为空
		tmpbuf = GetBufferObj();

#ifdef DEBUG_IOCP
		tmpbuf->sclient = sock->s;
#endif

		memcpy(tmpbuf->buf,buffer,len2);
		tmpbuf->buflen = len2;

		rc = PostSend(sock,tmpbuf);
		if(rc == 0)
			sock->sendobj = tmpbuf;
		else
			FreeBufferObj(tmpbuf);

	}
	else
	{  
		while(tmpbuf->next)
		{
			tmpbuf = tmpbuf->next;
			i++;
		}

		if(i > MAX_UNSENDS_COUNT) 
		{
			rc = -1;
			CloseSock(sock);
		} 
		else
		{
			if(tmpbuf->buflen + len2 > DEFAULT_BUFFER_SIZE)
			{

				tmpbuf->next = GetBufferObj();
				tmpbuf = tmpbuf->next;
			}
			memcpy(tmpbuf->buf+tmpbuf->buflen,buffer,len2);
			tmpbuf->buflen += len2;
		}
	}

	len -= len2;
	buf2 = (char *)buffer+len2;

	while(rc == 0 && len >0)
	{
		len2 = len;

		if(len2 > DEFAULT_BUFFER_SIZE)
			len2 = DEFAULT_BUFFER_SIZE;

		tmpbuf->next = GetBufferObj();
		tmpbuf = tmpbuf->next;

		memcpy(tmpbuf->buf,buf2,len2);
		tmpbuf->buflen = len2;
		len -= len2;
		buf2 += len2;
		i++;

		if(i > MAX_UNSENDS_COUNT)
		{
#ifdef LOG_LEVEL1
			Log_Server.Write("Send(): 发送失败(当前用户的发送队列超出 %d!",MAX_UNSENDS_COUNT);
#endif
			rc = -1;			
			break;
		}
	}

	UNLOCK(&sock->cs);

	InterlockedDecrement(&sock->sending_count);

	return rc;
	//注意:在PostSend()里面,buflen被设置为DEFAULT_BUFFER_SIZE,Send()调用时候的数据不会添加到正在发送的BufferObj后面
}
Beispiel #22
0
//-----------------------------------------------------------------------------------
//		Purpose	:
//		Return	:
//-----------------------------------------------------------------------------------
// Called by App TH, Worker TH ( Send )
//-----------------------------------------------------------------------------------
int CNtlConnection::PushPacket(CNtlPacket * pPacket)
{
	FUNCTION_BEGIN();


	if( false == IsStatus( STATUS_ACTIVE ) )
	{
		return NTL_ERR_NET_CONNECTION_STATUS_WRONG;
	}


	if( false == pPacket->IsValidPacket() )
	{
		return NTL_ERR_NET_PACKET_INVALID;
	}

	m_mutexSend.Lock(); // ¹ØÀ¸·Î ³»¸®¸é µ¿±âÈ­°¡ ±úÁø´Ù [5/30/2008 SGpro]

	if( pPacket->GetPacketLen() > GetMaxSendPacketSize() )
	{
		m_mutexSend.Unlock();
		return NTL_ERR_NET_PACKET_EXCEED_ALLOWED_SIZE;
	}


	if( m_sendBuffer.GetPushAvailableSize() <= pPacket->GetUsedSize() )
	{
		if( false == IsSetControlFlag( CONTROL_FLAG_USE_SEND_QUEUE ) )
		{
			m_mutexSend.Unlock();
			return NTL_ERR_NET_SESSION_SEND_BUFFER_OVERFLOW;
		}
		else 
		{
			CNtlPacket * pQueuedPacket = new CNtlPacket( *pPacket );
			if( NULL == pQueuedPacket )
			{
				m_mutexSend.Unlock();
				return NTL_ERR_SYS_MEMORY_ALLOC_FAIL;
			}

			if( false == m_sendQueue.PushPacket( pQueuedPacket ) )
			{
				SAFE_DELETE( pQueuedPacket );

				m_mutexSend.Unlock();
				return NTL_ERR_NET_SESSION_SEND_BUFFER_OVERFLOW;
			}

			m_mutexSend.Unlock();
			return NTL_SUCCESS;
		}
	}

	//m_mutexSend.Lock(); //¿©±â¿¡ µÎ¸é µ¿±âÈ­°¡ ±úÁø´Ù [5/30/2008 SGpro]

	memcpy( m_sendBuffer.GetQueuePushPtr(), pPacket->GetPacketBuffer(), pPacket->GetUsedSize() );

	//  [9/10/2007 zeroera] : ¼³¸í : È¿À²¼ºÀ» À§ÇØ ÆÐŶ ¹öÆÛ¿¡ ÀÖ´Â µ¥ÀÌŸ¸¦ °¡Áö°í ¾Ïȣȭ ÇÑ´Ù
	CNtlPacket sendPacket( m_sendBuffer.GetQueuePushPtr() );
	BYTE bySequence = (BYTE) ( m_dwPacketSendCount & PACKET_MAX_SEQUENCE );
	SetSequence( sendPacket.GetPacketHeader(), bySequence );

	int rc = NTL_SUCCESS;

#if __SGPRO_BOTSYSTEM_SENDANDRECVTESTCODE__
#else
	if( m_pPacketEncoder )
	{
		rc = m_pPacketEncoder->TxEncrypt( sendPacket );
		if( NTL_SUCCESS != rc )
		{
			m_mutexSend.Unlock();
			return NTL_ERR_NET_PACKET_ENCRYPT_FAIL;
		}
	}
#endif

	m_sendBuffer.IncreasePushPos( pPacket->GetUsedSize() );
	IncreasePacketSend();


	if( false == m_bSending )
	{
		rc = PostSend();
		if( NTL_SUCCESS != rc )
		{
			m_mutexSend.Unlock();
			return rc;
		}

		m_bSending = true;
	}

	m_mutexSend.Unlock();


	return NTL_SUCCESS;
}
Beispiel #23
0
//-----------------------------------------------------------------------------------
//		Purpose	:
//		Return	:
//-----------------------------------------------------------------------------------
// Called by Worker TH ( IOCP )
//-----------------------------------------------------------------------------------
int CNtlConnection::CompleteSend(DWORD dwTransferedBytes)
{
	UNREFERENCED_PARAMETER( dwTransferedBytes );

	FUNCTION_BEGIN();


	IncreaseBytesSend( dwTransferedBytes );


	m_mutexSend.Lock();

	m_sendBuffer.IncreasePopPos( dwTransferedBytes );


	int rc = 0;
	if( IsSetControlFlag( CONTROL_FLAG_USE_SEND_QUEUE ) )
	{
		CNtlPacket * pSendPacket = m_sendQueue.PeekPacket();
		while( pSendPacket )
		{
			if( m_sendBuffer.GetPushAvailableSize() <= pSendPacket->GetUsedSize() )
			{
				break;
			}

			BYTE bySequence = (BYTE) ( m_dwPacketSendCount & PACKET_MAX_SEQUENCE );
			SetSequence( pSendPacket->GetPacketHeader(), bySequence );

			#if __SGPRO_BOTSYSTEM_SENDANDRECVTESTCODE__
			#else
			if( m_pPacketEncoder )
			{
				rc = m_pPacketEncoder->TxEncrypt( *pSendPacket );
				if( NTL_SUCCESS != rc )
				{
					m_mutexSend.Unlock();

					NTL_LOGDL( LOG_NETWORK, "Session[%X] TxEncrypt Error[%d:%s]", this, rc, NtlGetErrorMessage(rc) );
					return NTL_ERR_NET_PACKET_ENCRYPT_FAIL;
				}
			}
			#endif

			memcpy( m_sendBuffer.GetQueuePushPtr(), pSendPacket->GetPacketBuffer(), pSendPacket->GetUsedSize() );
			m_sendBuffer.IncreasePushPos( pSendPacket->GetUsedSize() );
			IncreasePacketSend();

			m_sendQueue.PopPacket();
			SAFE_DELETE( pSendPacket );

			pSendPacket = m_sendQueue.PeekPacket();
		}
	}


	if( m_sendBuffer.GetCurSize() )
	{
		rc = PostSend();
		if( NTL_SUCCESS != rc )
		{
			m_bSending = false;
			m_mutexSend.Unlock();
			//  [1/20/2007 zeroera] : ¼³¸í : Send¿¡ ÀÇÇÑ Close ±â´ÉÀ» ¸·À½. TH1ÀÌ Recv Áß¿¡ TH2 °¡ Send ÇÏ¿© CloseÇÏ°Ô µÇ¸é ¹®Á¦°¡ ¹ß»ý ÇÒ ¼ÒÁö°¡ ÀÖÀ½
			//return rc;
			Disconnect( false );

			NTL_LOGDL( LOG_NETWORK, "Session[%X] PostSend Error[%d:%s]", this, rc, NtlGetErrorMessage(rc) );
			return NTL_SUCCESS;
		}
	}
	else
	{
		m_bSending = false;
	}


	m_mutexSend.Unlock();

	//NTL_PRINT(PRINT_SYSTEM, "Session[%X]\tCompleteSend Complete SendBufferSize[%d] TotalSendBytes[%u]", this, m_sendBuffer.GetCurSize(), m_dwTotalSendSize );

	return NTL_SUCCESS;
}