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 }
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(); }
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; } } }
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; }
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(); }
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(); }
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(); } }
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(); }
void JTcpServer::ReadData(ULONG threadId, const char* buffer, long bufferSize) { if( OnRecvData ) OnRecvData(threadId, buffer, bufferSize); }
void JTcpSocket::ReadData(ULONG threadId, const char* buffer, long bufferSize) { if( m_sockAccept->IsConnected && OnRecvData ){ OnRecvData(buffer, bufferSize); } }
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; }