Esempio n. 1
0
void TcpSocket::OnRead(size_t len)
{
	/* This is called when the socket engine gets an event on the socket */

#ifdef NETLIB_IOCP
	if(!len)
	{
		/* socket disconnected */
		Disconnect();
		return;
	}

	/* IOCP is easy. */
	if(len != 0xFFFFFFFF)
		m_readBuffer->IncrementWritten(len);

	/* Wewt, we read again! */
	OnRecvData();

	if(!IsConnected())
		return;

	/* Setup another read event */
	WSABUF buf;
	buf.buf = (char*)m_readBuffer->GetBuffer();
	buf.len = m_readBuffer->GetSpace();

	DWORD recved;
	DWORD flags = 0;
	Overlapped * ov = new Overlapped;
	memset(ov, 0, sizeof(Overlapped));
	ov->m_op = IO_EVENT_READ;

	if(WSARecv(m_fd, &buf, 1, &recved, &flags, &ov->m_ov, 0) == SOCKET_ERROR)
	{
        if(WSAGetLastError() != WSA_IO_PENDING)
			Disconnect();
	}

#else

	/* Any other platform, we have to call recv() to actually get the data. */
	int bytes = recv(m_fd, (char*)m_readBuffer->GetBuffer(), m_readBuffer->GetSpace(), 0);

	/* Under some socket engines, if this returns 0, we're in deep poo poo. */
	/* Check if recv() failed. */
	if(bytes <= 0)
		Disconnect();			// whoopes. :P
	else
	{
		m_readBuffer->IncrementWritten(bytes);
		OnRecvData();
	}

#endif
}
Esempio n. 2
0
void JUdpSocket::Execute()
{
	while(1)
	{
		if( GetTerminateFlag() )
			break;
		
		if( !m_bOpen ){
			Sleep(50);
			continue;
		}

		if( !m_bLocalBinded && m_PortLocal != 0 ){
			m_SockLocal = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
			if( m_SockLocal != SOCKET_ERROR ){
				sockaddr_in sockAddrLocal;
				sockAddrLocal.sin_family = AF_INET;
				sockAddrLocal.sin_addr.s_addr = ::htonl(ADDR_ANY); 
				sockAddrLocal.sin_port = ::htons(m_PortLocal);
				BOOL enable = TRUE;
				::setsockopt(m_SockLocal, SOL_SOCKET, SO_REUSEADDR|SO_BROADCAST, (const char*)(&enable), sizeof(BOOL));
				long bufferSize = JSocketBufferSize;
				::setsockopt(m_SockLocal, SOL_SOCKET, SO_RCVBUF, (const char*)(&bufferSize), sizeof(bufferSize));
				::setsockopt(m_SockLocal, SOL_SOCKET, SO_SNDBUF, (const char*)(&bufferSize), sizeof(bufferSize));

				if( ::bind(m_SockLocal, (sockaddr*)(&sockAddrLocal), sizeof(sockAddrLocal)) != SOCKET_ERROR )
					m_bLocalBinded = true;				
			}
		}
		if( !m_bRemoteBinded && m_PortRemote != 0 ){
			HOSTENT* hostInfo;
			if( m_IpRemote == _T("") )
				hostInfo = ::gethostbyname("127.0.0.1");
			else
				hostInfo = ::gethostbyname(JStringToString(m_IpRemote).c_str());
			
			if( hostInfo ){
				m_SockAddrRemote.sin_family = AF_INET;
				m_SockAddrRemote.sin_addr.s_addr = ::htonl(((struct in_addr *)hostInfo->h_addr)->s_addr);
				m_SockAddrRemote.sin_port = ::htons(m_PortRemote);
				m_bRemoteBinded = true;
			}
		}
		if( m_bLocalBinded ){
			if( m_SockLocal && IsDataArrived(10) ){
				char buffer[65535];
				int addrSize = sizeof(m_SockAddrRemote);
				while( IsDataArrived(0) ){
					long rcvSize = ::recvfrom(m_SockLocal, buffer, 65535*sizeof(TCHAR), 0, (sockaddr*)(&m_SockAddrRemote), (int*)(&addrSize));
					if( rcvSize <= 0 )
						break;
					// callback function
					if( OnRecvData )
						OnRecvData(buffer, rcvSize);
				}
			}
		}
	}
	Close();
}
Esempio n. 3
0
void JPeerSocket::Execute()
{
	char buffer[65535];
	while(1){
		if( GetTerminateFlag() || m_socket == NULL )
			break;

		if( IsDataArrived(10) ){
			long recvSize = 0;
			while( IsDataArrived(0) ){
				recvSize = ::recv(m_socket, buffer, 65535*sizeof(TCHAR), 0);
				if( recvSize <= 0 )
					break;

				if( !m_bConnected )
					m_bConnected = true;
				if( OnRecvData )
					OnRecvData(ThreadId, buffer, recvSize);
			}
		}else{
			Sleep(25);
		}
	}
	Close();
}
void CNetPTCPConnection::DoRecv()
{
	CAutoLock Lock(m_RecvLock);

	while(true)
	{
		CEpollEventObject * pEpollEventObject=GetServer()->CreateEventObject();
		if(pEpollEventObject)
		{
			pEpollEventObject->SetType(IO_RECV);
			pEpollEventObject->SetParentID(GetID());

			int RecvSize=recv(
				m_Socket.GetSocket(),
				pEpollEventObject->GetDataBuff()->GetBuffer(),
				pEpollEventObject->GetDataBuff()->GetBufferSize(),
				0);

			if(RecvSize>0)
			{
				GetServer()->AddTCPRecvBytes(RecvSize);
				pEpollEventObject->GetDataBuff()->SetUsedSize(RecvSize);
				OnRecvData(*(pEpollEventObject->GetDataBuff()));
				GetServer()->DeleteEventObject(pEpollEventObject);
				continue;

			}
			else if(RecvSize==0)
			{
				GetServer()->DeleteEventObject(pEpollEventObject);
				PrintNetLog(0xffffffff,"CNetPTCPConnection收到连接关闭信号!");
				Disconnect();
				return;
			}
			else
			{
				GetServer()->DeleteEventObject(pEpollEventObject);

				int ErrorCode=errno;
				switch(ErrorCode)
				{
				case EAGAIN:
					return;
				default:
					PrintNetLog(0xffffffff,"CNetPTCPConnection::Recv失败(%u),Socket关闭",ErrorCode);
					Disconnect();
					return;
				}
			}
		}
		else
		{
			PrintNetLog(0xffffffff,"CNetPTCPConnection创建Recv用EpollEventObject失败!");
			Disconnect();
			return;
		}
	}
}
Esempio n. 5
0
int CNetConnection::Update(int ProcessPacketLimit)
{

	int PacketCount=0;
	//处理Connect
	if(m_Socket.GetState()==CNetSocket::SS_CONNECTING)
	{
		m_Socket.Connected();
		if(m_Socket.GetState()==CNetSocket::SS_CONNECTED)
		{			
			StartWork();				
		}
		if(m_Socket.GetState()==CNetSocket::SS_UNUSED)
		{
			OnConnection(FALSE);			
		}
	}
	else
	{
		CEpollEventObject * pEpollEventObject;
		while(m_RecvQueue.PopFront(pEpollEventObject))
		{				
			OnRecvData(*(pEpollEventObject->GetDataBuff()));
			GetServer()->DeleteEventObject(pEpollEventObject);
			PacketCount++;
			if(PacketCount>=ProcessPacketLimit)
				break;
		}			
	}

	//处理关闭
	if(m_WantClose)
	{
		if(m_UseSafeDisconnect)
		{
			if(m_SendQueue.GetObjectCount()<=0)
			{
				Disconnect();		
			}			
		}
		else
		{
			Disconnect();
		}
	}
	return PacketCount;
}
Esempio n. 6
0
void CAppCtrl::RunOne()
{
	//SL_APPSO->repeate_do();
	//获取当前时间,时,分
	time_t		timep;
	struct tm   *pTime; 
	time(&timep);
	pTime = localtime(&timep);

	m_Stat.Put(app_stat_mainloop);
	sl::uint NowTime = static_cast<sl::uint>(time(0));
	if(m_LastTime == 0 || NowTime != m_LastTime)  //每秒执行一次
	{
		++m_SecondCount;
		m_LastTime = NowTime;

		if(m_SecondCount % 60 == 0) //每分钟执行一次
		{
			m_MinitCount++;
			m_SecondCount = 0;
			DumpStatInfo();
			if(m_MinitCount >= 10)
			{
				m_MinitCount = 0;
				//每十分钟写一次在线玩家数量日志
			}
		}

		CheckSvrConnect();

	}
	
	///定时检查命令
	SL_CMDFACTORY->CheckTimeoutCmd();

	//处理与前端管道中数据,防止数据包过多累积
	OnRecvData(EDPID_CLIENT);

	///调用so的RunOnce
	//SL_APPSO->OneRunOne();

}
Esempio n. 7
0
void NetSocket::OnRecv(NetCompletionOP* recvOP, DWORD bytesTransfered)
{
    REFLIB_ASSERT_RETURN_IF_FAILED(recvOP, "NetIoBuffer is null");

    NetIoBuffer *ioBuffer = reinterpret_cast<NetIoBuffer*>(recvOP);
    MemoryBlock* buffer;

    if (buffer = ioBuffer->PopData())
    {
        OnRecvData(buffer->GetData(), bytesTransfered);
    }
    else
    {
        Disconnect(NetCloseType::NET_CTYPE_SYSTEM);
    }

    delete ioBuffer;
    _netStatus.fetch_and(~NET_STATUS_RECV_PENDING);

    PostRecv();
}
Esempio n. 8
0
void JSerialComm::RecvData()
{
    if( !m_bOpen || !m_bConnected ) {
        return;
    }
    if( m_handle ) {
        DWORD errors;
        COMSTAT stat;
        char buffer[65535];
        DWORD read_bytes = 0;
        DWORD length = 0;
        m_cs.Enter();
        ::ClearCommError(m_handle, &errors, &stat);
        BOOL result = ::ReadFile(m_handle, buffer, 65535, &length, &m_RecvOverlapped);
        if( m_bOverlapped && !result ) {
            if( GetLastError() == ERROR_IO_PENDING ) {
                while( ::GetOverlappedResult(m_handle, &m_RecvOverlapped, &length, false) == false ) {
                    if( GetTerminateFlag() ) {
                        break;
                    }
                    if( GetLastError() != ERROR_IO_INCOMPLETE ) {
                        break;
                    }
                    read_bytes += length; // ??
                }
                read_bytes += length; // ??
            }
        } else {
            read_bytes += length;
        }
        if( !GetTerminateFlag() && OnRecvData && read_bytes > 0 ) {
            OnRecvData(buffer, read_bytes);
        }
        m_cs.Leave();
    }
}
Esempio n. 9
0
void JTcpSocket::Execute()
{
	while(1)
	{
		if( GetTerminateFlag() ){
			break;
		}
		if( m_sockState == JIdle ){
			Sleep(50);
			continue;
		}

		m_cs.Enter();
		JSocketState state = m_sockState;
		bool isOpen = m_bOpen;
		m_cs.Leave();

		if( !isOpen ){
			Sleep(50);
			continue;
		}
		if( state == JCaller ){			
			m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
			if( m_socket != NULL && m_socket != SOCKET_ERROR ){
				BOOL bRsa = TRUE;
				::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)(&bRsa), sizeof(BOOL));
				long BufferSize = JSocketBufferSize;
				::setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char*)(&BufferSize), sizeof(long));
				::setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (const char*)(&BufferSize), sizeof(long));
				sockaddr_in addr;
				addr.sin_family = AF_INET;
				HOSTENT* hostinfo = NULL; 
				if( m_ip.empty() )
					hostinfo = ::gethostbyname("127.0.0.1");
				else
					hostinfo = ::gethostbyname(JStringToString(m_ip).c_str());
				
				if( hostinfo ){
					addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
					addr.sin_port = ::htons(m_port);
				}
				if( ::connect(m_socket, (const sockaddr*)(&addr), sizeof(addr)) != SOCKET_ERROR ){
					m_cs.Enter();
					m_sockState = JConnected;
					m_bConnected = true;
					m_cs.Leave();
				}else{
					Reopen();
				}
			}else{
				Reopen();
			}
		}
		else if( state == JListener ){
			m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
			if( m_socket == NULL && m_socket == SOCKET_ERROR ){
				Reopen();
			}
			else{
				BOOL bRsa = TRUE;
				::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)(&bRsa), sizeof(BOOL));
				long bufferSize = JSocketBufferSize;
				::setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char*)(&bufferSize), sizeof(long));
				::setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (const char*)(&bufferSize), sizeof(long));
				sockaddr_in addr;
				addr.sin_family = AF_INET;
				addr.sin_port = ::htons(m_port);
				addr.sin_addr.s_addr = ::htonl(ADDR_ANY);
				if( ::bind(m_socket, (LPSOCKADDR)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR ){
					Reopen();
				}
				else{
					sockaddr_in addr;
					int addrSize = sizeof(sockaddr_in);
					if( m_port == 0 && ::getsockname(m_socket, (LPSOCKADDR)&addr, &addrSize) != SOCKET_ERROR )
						m_portAuto = ::ntohs(addr.sin_port);
									
					if( ::listen(m_socket, SOMAXCONN) != SOCKET_ERROR ){
						m_cs.Enter();
						m_sockState = JListening;
						m_cs.Leave();
					}else{
						Reopen();
					}
				}
			}
		}
		else if( state == JListening ){
			sockaddr_in addr;
			int addrSize = sizeof(sockaddr_in);
			SOCKET accept_sock = ::accept(m_socket, (struct sockaddr*)&addr, &addrSize);
			if( accept_sock == INVALID_SOCKET || accept_sock == NULL ){
				::shutdown(accept_sock, SD_SEND);
				::closesocket(accept_sock);
			}else{
				// close listening socket
				::shutdown(m_socket, SD_SEND);
				::closesocket(m_socket);
				m_socket = NULL;

				long bufferSize = JSocketBufferSize;
				::setsockopt(accept_sock, SOL_SOCKET, SO_RCVBUF, (const char*)(&bufferSize), sizeof(long));
				::setsockopt(accept_sock, SOL_SOCKET, SO_SNDBUF, (const char*)(&bufferSize), sizeof(long));
				m_sockAccept = new JPeerSocket(accept_sock);
				if( m_sockAccept != NULL ){
					m_sockAccept->OnRecvData.Attach<JTcpSocket>(this, &JTcpSocket::ReadData);
					m_sockAccept->Open();
					m_cs.Enter();
					m_sockState = JConnected;
					m_bConnected = true;
					m_cs.Leave();
				}
			}
		}
		else if( state == JConnected ){
			if( !m_bListener ){
				char buffer[65535];
				if( IsDataArrived(10) ){
					long recvSize = 0;
					while( IsDataArrived(0) ){
						recvSize = ::recv(m_socket, buffer, 65535*sizeof(TCHAR), 0);
						if( recvSize <= 0 )
							break;
						
						if( OnRecvData && m_sockState == JConnected)
							OnRecvData(buffer, recvSize);
					}
				}else{
					//Sleep(50);
				}
			}else{
				Sleep(50);
			}
		}else{
			Sleep(50);
		}
	}
	//Close();
}
Esempio n. 10
0
void JTcpServer::ReadData(ULONG threadId, const char* buffer, long bufferSize)
{
	if( OnRecvData )
		OnRecvData(threadId, buffer, bufferSize);
}
Esempio n. 11
0
void JTcpSocket::ReadData(ULONG threadId, const char* buffer, long bufferSize)
{
	if( m_sockAccept->IsConnected && OnRecvData ){
		OnRecvData(buffer, bufferSize);
	}
}
Esempio n. 12
0
SInt64 RTTcp::Run()
{
	EventFlags events = this->GetEvents();
	this->ForceSameThread();
	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
	{
        if (events&Task::kTimeoutEvent) {
            LI("%s timeout \n", __FUNCTION__);
        } else {
            LI("%s kill \n", __FUNCTION__);
        }
        std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this);
        if (it != m_mapConnectObserver.end()) {
            LI("Tcp::Run find Disconnection\n");
            RTObserverConnection *conn = it->second;
            if (conn) {
                LI("Tcp::Run notify Disconnection\n");
                conn->ConnectionDisconnected();
            }
        }
		return -1;
	}


	while(this->IsLiveSession())
	{
		if(events&Task::kReadEvent)
		{
			UInt32	readed = 0;
			char	fRequestBuffer[kRequestBufferSizeInBytes];
			while(1)
			{
				readed = 0;
				// We don't have any new data, get some from the socket...
				OS_Error sockErr = fSocket.Read(fRequestBuffer, kRequestBufferSizeInBytes - 1, &readed);
				if (sockErr == EAGAIN)
					break;

				if (sockErr != OS_NoErr)
				{
					Assert(!fSocket.IsConnected());
					break;
				}

				if(readed > 0)
				{
					OnRecvData(fRequestBuffer, readed);
				}
			}

			fSocket.RequestEvent(EV_RE);
			events -= Task::kReadEvent; 
		}
		else if(events&Task::kWriteEvent)
		{
			ListElement *elem = NULL; 
			if((elem = m_listSend.first) != NULL) 
			{ 
				UInt32 theLengthSent = 0;
				OS_Error err = fSocket.Send((char*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&m_listSend); 
					if(NULL != m_listSend.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent; 
		}
		else if(events&Task::kLcsEvent)
		{
			OnLcsEvent();
			events -= Task::kLcsEvent;
		}
		else if(events&Task::kPeerEvent)
		{
			OnPeerEvent();
			events -= Task::kPeerEvent; 
		}
		else if(events&Task::kIdleEvent)
		{
			OnTickEvent();
			events -= Task::kIdleEvent; 
		}
		else
		{
			return fTickTime;
		}
	}

	// If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this);
    if (it != m_mapConnectObserver.end()) {
        LI("Tcp::Run SessionOffline  find Disconnection\n");
        RTObserverConnection *conn = it->second;
        if (conn) {
            LI("Tcp::Run SessionOffline notify Disconnection\n");
            conn->ConnectionDisconnected();
        }
    }
    return -1;
}