inline AM_ERR CMp4Muxer::OnEOF(CPacket *packet) { AM_INT i = 0; if (!mbRun) return ME_OK; if (packet->GetAttr () == CPacket::AM_PAYLOAD_ATTR_VIDEO) { //video EOF mEOFMap |= 0x1 << 1; } else if (packet->GetAttr () == CPacket::AM_PAYLOAD_ATTR_AUDIO) { //audio EOF mEOFMap |= 0x1 << 0; } else { NOTICE ("Currently, MP4 muxer just support audio and video stream.\n"); return ME_ERROR; } if (mEOFMap == 0x3) { mpMP4Builder->FinishProcess(); mpDataWriter->OnEOF (); mEOFMap = 0; mpMP4Builder->InitProcess(); mNextFileBoundary = mLastVideoPTS + mSplittedDuration; mbIsFirstVideo = true; mbIsFirstAudio = true; for (i = 0; i <= mCountBuffer; i++) { OnData(mBuffer[i]); mBuffer[i]->Release(); } mCountBuffer = -1; INFO("Next file boundary is %llu", mNextFileBoundary); } return ME_OK; }
bool STNetEngine::WINIO(int timeout) { #ifdef WIN32 STIocp::IO_EVENT e; if ( !m_pNetMonitor->WaitEvent( e, timeout ) ) return false; switch( e.type ) { case STIocp::timeout : break; case STIocp::stop : return false; break; case STIocp::connect : OnConnect( e.client, false ); m_pNetMonitor->AddAccept( e.sock ); break; case STIocp::recv : OnData( e.sock, e.pData, e.uDataSize ); break; case STIocp::close : OnClose( e.sock ); break; case STIocp::send : OnSend( e.sock, e.uDataSize ); break; default: break; } return true; #endif return false; }
void CExternalIPResolver::OnClose() { if (m_data != _T("")) OnData(0, 0); else Close(false); }
CAVCDecoderConfigurationRecord::CAVCDecoderConfigurationRecord(void* buf) { memset(this, 0, sizeof(*this)); m_p_sequenceParameterSetNALUnit = NULL; m_p_pictureParameterSetNALUnit = NULL; OnData(buf); }
inline AM_ERR CMp4Muxer::OnAVData(CPacket *packet) { if (AM_UNLIKELY(packet->mPacketType & CPacket::AM_PACKET_TYPE_SYNC)) { /*Event pointer equals normal pointer*/ mEventNormalSync = 1; if (mEventMap == 0){ return OnData(packet); } else { return OnEventData(packet); } } /* mEventMap determins calling which function, * mEventNormalSync and mPacketType * determin getting which type packet */ if (mEventMap == 0 && ((mEventNormalSync == 1 && packet->mPacketType == CPacket::AM_PACKET_TYPE_NORMAL) || (mEventNormalSync == 0 && packet->mPacketType == CPacket::AM_PACKET_TYPE_EVENT))) { /*Normal recording*/ return OnData(packet); } else if (mEventMap == 1 && ((mEventNormalSync == 1 && packet->mPacketType == CPacket::AM_PACKET_TYPE_NORMAL) || (mEventNormalSync == 0 && packet->mPacketType == CPacket::AM_PACKET_TYPE_EVENT))) { /*Event recording*/ return OnEventData(packet); } else if (mEventMap == 1 && (packet->mPacketType & CPacket::AM_PACKET_TYPE_STOP)) { /*Switch to normal recording*/ mpMP4Builder->FinishProcess(); mpDataWriter->OnEOF (); mEventMap = 0; mpMP4Builder->InitProcess(); mNextFileBoundary = mLastVideoPTS + mSplittedDuration; return OnData(packet); } else { DEBUG("Discard the packet"); } return ME_OK; }
void WebsocketTransport::AddEventListeners() { ws_->set_on_open([this]{ OnOpen(); }); ws_->set_on_close([this]{ OnClose(); }); ws_->set_on_message([this](const Websocket::Message & message){ OnData(message); }); ws_->set_on_error([this](const std::string & error){ OnError(Format("websocket error: %s", error.c_str())); }); }
void CExternalIPResolver::OnReceive() { if (!m_pRecvBuffer) { m_pRecvBuffer = new char[m_recvBufferLen]; m_recvBufferPos = 0; } if (m_pSendBuffer) return; while (m_pSocket) { unsigned int len = m_recvBufferLen - m_recvBufferPos; int error; int read = m_pSocket->Read(m_pRecvBuffer + m_recvBufferPos, len, error); if (read == -1) { if (error != EAGAIN) Close(false); return; } if (!read) { Close(false); return; } if (m_finished) { // Just ignore all further data m_recvBufferPos = 0; return; } m_recvBufferPos += read; if (!m_gotHeader) OnHeader(); else { if (m_transferEncoding == chunked) OnChunkedData(); else OnData(m_pRecvBuffer, m_recvBufferPos); } } }
// called from ---NETPLAY--- thread void NetPlayClient::ThreadFunc() { while (m_do_loop.load()) { ENetEvent netEvent; int net; if (m_traversal_client) m_traversal_client->HandleResends(); net = enet_host_service(m_client, &netEvent, 250); while (!m_async_queue.Empty()) { Send(*(m_async_queue.Front().get())); m_async_queue.Pop(); } if (net > 0) { sf::Packet rpac; switch (netEvent.type) { case ENET_EVENT_TYPE_RECEIVE: rpac.append(netEvent.packet->data, netEvent.packet->dataLength); OnData(rpac); enet_packet_destroy(netEvent.packet); break; case ENET_EVENT_TYPE_DISCONNECT: m_is_running.store(false); NetPlay_Disable(); m_dialog->AppendChat("< LOST CONNECTION TO SERVER >"); PanicAlertT("Lost connection to server!"); m_do_loop.store(false); netEvent.peer->data = nullptr; break; default: break; } } } Disconnect(); return; }
BrowserClient::BrowserClient(RocketWebBrowser *listener, QTcpSocket *socket_) : socket(socket_) { connect(socket, SIGNAL(readyRead()), SLOT(OnData()), Qt::UniqueConnection); connect(socket, SIGNAL(disconnected()), listener, SLOT(ConnectionLost()), Qt::QueuedConnection); connect(this, SIGNAL(UrlRequest(const BrowserProtocol::UrlMessage&)), listener, SLOT(OnUrlRequest(const BrowserProtocol::UrlMessage&))); connect(this, SIGNAL(ResizeRequest(const BrowserProtocol::ResizeMessage&)), listener, SLOT(OnResizeRequest(const BrowserProtocol::ResizeMessage&))); connect(this, SIGNAL(MouseMoveRequest(const BrowserProtocol::MouseMoveMessage&)), listener, SLOT(OnMouseMoveRequest(const BrowserProtocol::MouseMoveMessage&))); connect(this, SIGNAL(MouseButtonRequest(const BrowserProtocol::MouseButtonMessage&)), listener, SLOT(OnMouseButtonRequest(const BrowserProtocol::MouseButtonMessage&))); connect(this, SIGNAL(KeyboardRequest(const BrowserProtocol::KeyboardMessage&)), listener, SLOT(OnKeyboardRequest(const BrowserProtocol::KeyboardMessage&))); connect(this, SIGNAL(TypedRequest(const BrowserProtocol::TypedMessage&)), listener, SLOT(OnTypedRequest(const BrowserProtocol::TypedMessage&))); }
// called from ---NETPLAY--- thread void NetPlayClient::ThreadFunc() { while (m_do_loop.IsSet()) { ENetEvent netEvent; int net; if (m_traversal_client) m_traversal_client->HandleResends(); net = enet_host_service(m_client, &netEvent, 250); while (!m_async_queue.Empty()) { Send(*(m_async_queue.Front().get())); m_async_queue.Pop(); } if (net > 0) { sf::Packet rpac; switch (netEvent.type) { case ENET_EVENT_TYPE_RECEIVE: rpac.append(netEvent.packet->data, netEvent.packet->dataLength); OnData(rpac); enet_packet_destroy(netEvent.packet); break; case ENET_EVENT_TYPE_DISCONNECT: m_dialog->OnConnectionLost(); if (m_is_running.IsSet()) StopGame(); break; default: break; } } } Disconnect(); return; }
void OnCommand( HWND hWnd, WPARAM wParam ) { switch( LOWORD(wParam) ) { case 1001: if( HIWORD(wParam)==CBN_SELCHANGE ) { HWND hSimple = GetDlgItem( hWnd, 1001 ); HWND hDropDown = GetDlgItem( hWnd, 1002 ); HWND hDropList = GetDlgItem( hWnd, 1003 ); LRESULT nSel = SendMessage( hSimple, CB_GETCURSEL, 0, 0 ); SendMessage(hDropDown,CB_SETCURSEL,nSel,0); SendMessage(hDropList,CB_SETCURSEL,nSel,0); }else if( HIWORD(wParam)==CBN_EDITCHANGE ) { MessageBox(hWnd,"键盘输入内容有变化","Infor", MB_OK ); } break; case ID_DATA: OnData( hWnd );//获取选择项的附加数据 break; case ID_TEXT: OnText( hWnd );//获取选择项文本内容 break; case ID_FIND: OnFind( hWnd );//匹配选项 break; case ID_DELETE: OnDelete( hWnd );//删除选择项 break; case ID_CLEAR: OnClear( hWnd );//清空选项 break; case ID_ADD: OnAdd( hWnd );//添加选项 break; } }
void WebsocketTransport::Open() { auto thiz = std::static_pointer_cast<WebsocketTransport>(shared_from_this()); auto query = MergeQuery(socket_->options().query.value(), ""); websocket_ = Websocket::Create(PrepareUrl() + query, ""); websocket_->set_on_open([thiz](){ thiz->OnOpen(); thiz->socket()->SetBuffer(false); }); websocket_->set_on_message([thiz](const Websocket::Message & message){ thiz->OnData(ToString(*message.data)); }); websocket_->set_on_close([thiz](){ thiz->OnClose(); thiz->socket()->SetBuffer(true); }); websocket_->set_on_error([thiz](const std::string & error){ thiz->OnError(error); }); }
void OnCommand(HWND hWnd,WPARAM wParam){ switch(LOWORD(wParam)){ case 1001: if(HIWORD(wParam) == CBN_SELCHANGE){ HWND hSimple = GetDlgItem(hWnd,1001); HWND hDropDown = GetDlgItem(hWnd,1002); HWND hDropList = GetDlgItem(hWnd,1003); LRESULT nRet = SendMessage(hSimple,CB_GETCURSEL,0,0); SendMessage(hDropDown,CB_SETCURSEL,nRet,0); SendMessage(hDropList,CB_SETCURSEL,nRet,0); } else if(HIWORD(wParam) == CBN_EDITCHANGE ){ MessageBox(hWnd,"Keyboard Input changes","Info",MB_OK); } break; case ID_DATA: OnData(hWnd); break; case ID_DIR: OnDir(hWnd); break; case ID_TEXT: OnText(hWnd); break; case ID_FIND: OnFind(hWnd); break; case ID_ADD: OnAdd(hWnd); break; case ID_CLEAN: OnClean(hWnd); break; case ID_DELETE: OnDelete(hWnd); break; } }
void dhla::net::TCPSocket::PollEventsSync() { while(connected) { // creating a set of sockets, in order to poll its events fd_set readset; FD_ZERO(&readset); FD_SET(m_fd, &readset); // only one socket for this time // critical section MutexLock(); int result = select(0, &readset, NULL, NULL, NULL ); MutexUnlock(); // ends critical section if(result == 0 || result == SOCKET_ERROR) { if(OnError) { OnError(this, "Error waiting for socket's events", WSAGetLastError()); break; } else { throw "Error waiting for socket's events"; } } else { int len = recv(m_fd, m_input_buffer, MAX_BUFFER_SIZE, 0); if(len < 1) { if(OnClose && connected) { connected = false; OnClose(this); } break; } if(OnData != NULL) { OnData(this, m_input_buffer, len); } } } }
bool HTTPSocket::ProcessReceivedData(char *errbuf) { if (errbuf) errbuf[0] = 0; if (!recvbuf) return true; char *buff=(char *)recvbuf; unsigned long bufflen=recvbuf_used; while(1) { if (m_header) { char *ptr=(char *)memchr(buff,'\n',bufflen); if (!ptr) break; int length=(ptr-buff)+1; std::string line; line.append(buff,length-2); OnLine(line); buff+=length; bufflen-=length; } else { OnData(buff,bufflen); buff+=bufflen; bufflen=0; break; } } if (bufflen) { memmove(recvbuf,buff,bufflen); recvbuf_used=bufflen; } else { safe_delete_array(recvbuf); } }
void ASyncTCP::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { OnData(m_buffer,bytes_transferred); //Read next //This gives some work to the io_service before it is started mIos.post(boost::bind(&ASyncTCP::read, this)); } else { // try to reconnect if external host disconnects if (!mIsClosing) { mIsConnected = false; // let listeners know OnError(error); if (!mDoReconnect) { OnDisconnect(); return; } if (!mIsReconnecting) { mIsReconnecting = true; _log.Log(LOG_STATUS, "TCP: Reconnecting in %d seconds...", RECONNECT_TIME); // schedule a timer to reconnect after 30 seconds mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME)); mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error)); } } else do_close(); } }
void HTTPSocket::OnRawData(const char *buf,size_t len) { if (!m_header) { if (m_b_chunked) { size_t ptr = 0; while (ptr < len) { switch (m_chunk_state) { case 4: while (ptr < len && (m_chunk_line.size() < 2 || m_chunk_line.substr(m_chunk_line.size() - 2) != "\r\n")) m_chunk_line += buf[ptr++]; if (m_chunk_line.size() > 1 && m_chunk_line.substr(m_chunk_line.size() - 2) == "\r\n") { OnDataComplete(); // prepare for next request(or response) m_b_chunked = false; SetLineProtocol( true ); m_first = true; m_header = true; m_body_size_left = 0; if (len - ptr > 0) { char tmp[TCP_BUFSIZE_READ]; memcpy(tmp, buf + ptr, len - ptr); tmp[len - ptr] = 0; OnRead( tmp, len - ptr ); ptr = len; } } break; case 0: while (ptr < len && (m_chunk_line.size() < 2 || m_chunk_line.substr(m_chunk_line.size() - 2) != "\r\n")) m_chunk_line += buf[ptr++]; if (m_chunk_line.size() > 1 && m_chunk_line.substr(m_chunk_line.size() - 2) == "\r\n") { m_chunk_line.resize(m_chunk_line.size() - 2); Parse pa(m_chunk_line, ";"); std::string size_str = pa.getword(); m_chunk_size = Utility::hex2unsigned(size_str); if (!m_chunk_size) { m_chunk_state = 4; m_chunk_line = ""; } else { m_chunk_state = 1; m_chunk_line = ""; } } break; case 1: { size_t left = len - ptr; size_t sz = m_chunk_size < left ? m_chunk_size : left; OnData(buf + ptr, sz); m_chunk_size -= sz; ptr += sz; if (!m_chunk_size) { m_chunk_state = 2; } } break; case 2: // skip CR ptr++; m_chunk_state = 3; break; case 3: // skip LF ptr++; m_chunk_state = 0; break; } } } else if (!m_b_http_1_1 || !m_b_keepalive) { OnData(buf, len); /* request is HTTP/1.0 _or_ HTTP/1.1 and not keep-alive This means we destroy the connection after the response has been delivered, hence no need to reset all internal state variables for a new incoming request. */ m_body_size_left -= len; if (!m_body_size_left) { OnDataComplete(); } } else { size_t sz = m_body_size_left < len ? m_body_size_left : len; OnData(buf, sz); m_body_size_left -= sz; if (!m_body_size_left) { OnDataComplete(); // prepare for next request(or response) SetLineProtocol( true ); m_first = true; m_header = true; m_body_size_left = 0; if (len - sz > 0) { char tmp[TCP_BUFSIZE_READ]; memcpy(tmp, buf + sz, len - sz); tmp[len - sz] = 0; OnRead( tmp, len - sz ); } } } } }
void EpollFrame::DataMonitor() { #ifndef WIN32 int nCount = MAXPOLLSIZE; epoll_event *events = new epoll_event[nCount]; //epoll事件 int i = 0; map<int64,int> ioList; map<int64,int>::iterator it; bool ret = false; while ( !m_stop ) { //没有可io的socket则等待新可io的socket //否则检查是否有新的可io的socket,有则取出加入到ioList中,没有也不等待 //继续进行ioList中的socket进行io操作 nCount = MAXPOLLSIZE; if ( 0 >= ioList.size() ) ret = ((EpollMonitor*)m_pNetMonitor)->WaitData( events, nCount, -1 ); else ret = ((EpollMonitor*)m_pNetMonitor)->WaitData( events, nCount, 0 ); if ( !ret ) break; //加入到ioList中 for ( i = 0; i < nCount; i++ ) { if ( ((EpollMonitor*)m_pNetMonitor)->IsStop(events[i].data.u64) ) { delete[]events; return; } //对于recv send则加入到io列表,统一调度 it = ioList.find(events[i].data.u64); if ( it != ioList.end() ) continue; ioList.insert(map<int64,int>::value_type(events[i].data.u64, 1) );//增加可io的对象 } //遍历ioList,执行1次io for ( it = ioList.begin(); it != ioList.end(); it++ ) { if ( 1&it->second ) //可读 { if ( ok != OnData( it->first, 0, 0 ) ) //数据已读完或连接已断开 { it->second = it->second&~1;//清除事件 } } } //将不可io的socket清除 it = ioList.begin(); while ( it != ioList.end() ) { if ( 0 == it->second ) { ioList.erase(it); it = ioList.begin(); } else it++; } } #endif }
void CExternalIPResolver::OnHeader() { // Parse the HTTP header. // We do just the neccessary parsing and silently ignore most header fields // Redirects are supported though if the server sends the Location field. while (true) { // Find line ending unsigned int i = 0; for (i = 0; (i + 1) < m_recvBufferPos; i++) { if (m_pRecvBuffer[i] == '\r') { if (m_pRecvBuffer[i + 1] != '\n') { Close(false); return; } break; } } if ((i + 1) >= m_recvBufferPos) { if (m_recvBufferPos == m_recvBufferLen) { // We don't support header lines larger than 4096 Close(false); return; } return; } m_pRecvBuffer[i] = 0; if (!m_responseCode) { m_responseString = wxString(m_pRecvBuffer, wxConvLocal); if (m_recvBufferPos < 16 || memcmp(m_pRecvBuffer, "HTTP/1.", 7)) { // Invalid HTTP Status-Line Close(false); return; } if (m_pRecvBuffer[9] < '1' || m_pRecvBuffer[9] > '5' || m_pRecvBuffer[10] < '0' || m_pRecvBuffer[10] > '9' || m_pRecvBuffer[11] < '0' || m_pRecvBuffer[11] > '9') { // Invalid response code Close(false); return; } m_responseCode = (m_pRecvBuffer[9] - '0') * 100 + (m_pRecvBuffer[10] - '0') * 10 + m_pRecvBuffer[11] - '0'; if (m_responseCode >= 400) { // Failed request Close(false); return; } if (m_responseCode == 305) { // Unsupported redirect Close(false); return; } } else { if (!i) { // End of header, data from now on // Redirect if neccessary if (m_responseCode >= 300) { delete m_pSocket; m_pSocket = 0; delete [] m_pRecvBuffer; m_pRecvBuffer = 0; wxString location = m_location; ResetHttpData(false); GetExternalIP(location, m_protocol); return; } m_gotHeader = true; memmove(m_pRecvBuffer, m_pRecvBuffer + 2, m_recvBufferPos - 2); m_recvBufferPos -= 2; if (m_recvBufferPos) { if (m_transferEncoding == chunked) OnChunkedData(); else OnData(m_pRecvBuffer, m_recvBufferPos); } return; } if (m_recvBufferPos > 12 && !memcmp(m_pRecvBuffer, "Location: ", 10)) { m_location = wxString(m_pRecvBuffer + 10, wxConvLocal); } else if (m_recvBufferPos > 21 && !memcmp(m_pRecvBuffer, "Transfer-Encoding: ", 19)) { if (!strcmp(m_pRecvBuffer + 19, "chunked")) m_transferEncoding = chunked; else if (!strcmp(m_pRecvBuffer + 19, "identity")) m_transferEncoding = identity; else m_transferEncoding = unknown; } } memmove(m_pRecvBuffer, m_pRecvBuffer + i + 2, m_recvBufferPos - i - 2); m_recvBufferPos -= i + 2; if (!m_recvBufferPos) break; } }
bool STNetEngine::LinuxIO( int timeout ) { #ifndef WIN32 int nCount = 0; int eventType = 0; int i = 0; Socket sockListen; Socket sockClient; SOCKET sock; map<SOCKET,int>::iterator it; pair<map<SOCKET,int>::iterator,bool> ret; //没有可io的socket则等待新可io的socket //否则检查是否有新的可io的socket,有则取出加入到m_ioList中,没有也不等待 //继续进行m_ioList中的socket进行io操作 if ( 0 >= m_ioList.size() ) nCount = m_pNetMonitor->WaitEvent( timeout ); else nCount = m_pNetMonitor->WaitEvent( 0 ); if ( 0 > nCount ) return false; //加入到m_ioList中 for ( i = 0; i < nCount; i++ ) { sock = m_pNetMonitor->GetSocket(i); if ( INVALID_SOCKET == sock ) return false;//STEpoll已关闭 if ( m_pNetMonitor->IsAcceptAble(i) )//连接类型直接执行业务 { while ( true ) { sockListen.Detach(); sockListen.Attach(sock); sockListen.Accept( sockClient ); if ( INVALID_SOCKET == sockClient.GetSocket() ) break; sockClient.SetSockMode(); OnConnect(sockClient.Detach(), false); } continue; } //不是监听socket一定是io事件 //加入到io列表,统一调度 if ( m_pNetMonitor->IsWriteAble(i) ) eventType = 1|2;//recv+send事件 else eventType = 1;//recv事件 ret = m_ioList.insert(map<SOCKET,int>::value_type(sock,eventType) );//增加可io的对象 if ( !ret.second ) ret.first->second = ret.first->second|eventType;//设置新事件 } //遍历m_ioList,执行1次io for ( it = m_ioList.begin(); it != m_ioList.end(); it++ ) { if ( 1&it->second ) //可读 { if ( ok != OnData( it->first, 0, 0 ) ) //数据已读完或连接已断开 { it->second = it->second&~1;//清除事件 } } if ( 2&it->second ) //可写 { if ( ok != OnSend( it->first, 0 ) )//数据已经发送完,或socket已经断开,或socket不可写 { it->second = it->second&~2;//清除事件 } } } //将不可io的socket清除 it = m_ioList.begin(); while ( it != m_ioList.end() ) { if ( 0 == it->second ) { m_ioList.erase(it); it = m_ioList.begin(); continue; } it++; } return true; #endif return false; }
void CExternalIPResolver::OnChunkedData() { char* p = m_pRecvBuffer; unsigned int len = m_recvBufferPos; while (true) { if (m_chunkData.size != 0) { unsigned int dataLen = len; if (m_chunkData.size < len) dataLen = m_chunkData.size.GetLo(); OnData(p, dataLen); if (!m_pRecvBuffer) return; m_chunkData.size -= dataLen; p += dataLen; len -= dataLen; if (m_chunkData.size == 0) m_chunkData.terminateChunk = true; if (!len) break; } // Find line ending unsigned int i = 0; for (i = 0; (i + 1) < len; i++) { if (p[i] == '\r') { if (p[i + 1] != '\n') { Close(false); return; } break; } } if ((i + 1) >= len) { if (len == m_recvBufferLen) { // We don't support lines larger than 4096 Close(false); return; } break; } p[i] = 0; if (m_chunkData.terminateChunk) { if (i) { // Chunk has to end with CRLF Close(false); return; } m_chunkData.terminateChunk = false; } else if (m_chunkData.getTrailer) { if (!i) { m_finished = true; m_recvBufferPos = 0; return; } // Ignore the trailer } else { // Read chunk size char* q = p; while (*q) { if (*q >= '0' && *q <= '9') { m_chunkData.size *= 16; m_chunkData.size += *q - '0'; } else if (*q >= 'A' && *q <= 'F') { m_chunkData.size *= 10; m_chunkData.size += *q - 'A' + 10; } else if (*q >= 'a' && *q <= 'f') { m_chunkData.size *= 10; m_chunkData.size += *q - 'a' + 10; } else if (*q == ';' || *q == ' ') break; else { // Invalid size Close(false); return; } q++; } if (m_chunkData.size == 0) m_chunkData.getTrailer = true; } p += i + 2; len -= i + 2; if (!len) break; } if (p != m_pRecvBuffer) { memmove(m_pRecvBuffer, p, len); m_recvBufferPos = len; } }
// called from ---NETPLAY--- thread void NetPlayServer::ThreadFunc() { while (m_do_loop) { // update pings every so many seconds if ((m_ping_timer.GetTimeElapsed() > (10 * 1000)) || m_update_pings) { //PanicAlertT("Sending pings"); m_ping_key = Common::Timer::GetTimeMs(); sf::Packet spac; spac << (MessageId)NP_MSG_PING; spac << m_ping_key; std::lock_guard<std::recursive_mutex> lks(m_crit.send); m_ping_timer.Start(); SendToClients(spac); m_update_pings = false; } // check which sockets need attention const unsigned int num = m_selector.Wait(0.01f); for (unsigned int i=0; i<num; ++i) { sf::SocketTCP ready_socket = m_selector.GetSocketReady(i); // listening socket if (ready_socket == m_socket) { sf::SocketTCP accept_socket; m_socket.Accept(accept_socket); unsigned int error; { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); error = OnConnect(accept_socket); } if (error) { sf::Packet spac; spac << (MessageId)error; // don't need to lock, this client isn't in the client map accept_socket.Send(spac); // TODO: not sure if client gets the message if i close right away accept_socket.Close(); } } // client socket else { sf::Packet rpac; switch (ready_socket.Receive(rpac)) { case sf::Socket::Done : // if a bad packet is received, disconnect the client if (0 == OnData(rpac, ready_socket)) break; //case sf::Socket::Disconnected : default : { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); OnDisconnect(ready_socket); break; } } } } } // close listening socket and client sockets { std::map<sf::SocketTCP, Client>::reverse_iterator i = m_players.rbegin(), e = m_players.rend(); for ( ; i!=e; ++i) i->second.socket.Close(); } return; }
// called from ---NETPLAY--- thread void NetPlayServer::ThreadFunc() { while (m_do_loop) { // update pings every so many seconds if ((m_ping_timer.GetTimeElapsed() > 1000) || m_update_pings) { m_ping_key = Common::Timer::GetTimeMs(); sf::Packet spac; spac << (MessageId)NP_MSG_PING; spac << m_ping_key; m_ping_timer.Start(); SendToClients(spac); m_update_pings = false; } ENetEvent netEvent; int net; if (m_traversal_client) m_traversal_client->HandleResends(); net = enet_host_service(m_server, &netEvent, 1000); while (!m_async_queue.Empty()) { { std::lock_guard<std::recursive_mutex> lkp(m_crit.players); SendToClients(m_async_queue.Front()); } m_async_queue.Pop(); } if (net > 0) { switch (netEvent.type) { case ENET_EVENT_TYPE_CONNECT: { ENetPeer* accept_peer = netEvent.peer; unsigned int error; { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); error = OnConnect(accept_peer); } if (error) { sf::Packet spac; spac << (MessageId)error; // don't need to lock, this client isn't in the client map Send(accept_peer, spac); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } enet_peer_disconnect_later(accept_peer, 0); } } break; case ENET_EVENT_TYPE_RECEIVE: { sf::Packet rpac; rpac.append(netEvent.packet->data, netEvent.packet->dataLength); auto it = m_players.find(*(PlayerId*)netEvent.peer->data); Client& client = it->second; if (OnData(rpac, client) != 0) { // if a bad packet is received, disconnect the client std::lock_guard<std::recursive_mutex> lkg(m_crit.game); OnDisconnect(client); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } } enet_packet_destroy(netEvent.packet); } break; case ENET_EVENT_TYPE_DISCONNECT: { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); if (!netEvent.peer->data) break; auto it = m_players.find(*(PlayerId*)netEvent.peer->data); if (it != m_players.end()) { Client& client = it->second; OnDisconnect(client); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } } } break; default: break; } } } // close listening socket and client sockets for (auto& player_entry : m_players) { delete (PlayerId*)player_entry.second.socket->data; player_entry.second.socket->data = nullptr; enet_peer_disconnect(player_entry.second.socket, 0); } }
void Socket::ProcessEvents (unsigned long _lMillisecTimeout) { if (false == b_Standalone) { cerr << "[ERROR] Calling Socket::ProcessEvent directly on a non-standalone socket!" << endl; return; } fd_set fsReadReady; fd_set fsWriteReady; fd_set fsError; FD_ZERO (&fsReadReady); FD_ZERO (&fsWriteReady); FD_ZERO (&fsError); if ((SOCKET_FD_UNDEF == fd_Socket) || (SOCKET_FD_CLOSED == fd_Socket) || (SOCKET_FD_DESTROYED == fd_Socket)) { usleep (_lMillisecTimeout * 1000); return; } if ((Socket::InProgress != e_ConnectionStatus) || (NonBlocking != e_BlockingType)) FD_SET (fd_Socket, &fsReadReady); FD_SET (fd_Socket, &fsError); // check for write ready only for sockets waiting // to send data ... if (o_SendBuffer.Length () > 0) FD_SET (fd_Socket, &fsWriteReady); // checking for write ready on non-blocking sockets // in the process of being connected tell us when // they do get connected ... if (Socket::InProgress == e_ConnectionStatus) FD_SET (fd_Socket, &fsWriteReady); timeval oTimeout; oTimeout.tv_sec = _lMillisecTimeout / 1000; oTimeout.tv_usec = (_lMillisecTimeout * 1000) % 1000000; select (fd_Socket + 1, &fsReadReady, &fsWriteReady, &fsError, &oTimeout); // Note that a socket might become disconnected through // the functionality of inherited classes in response // to the virtual method calls made here. So we need // to check after each call if the socket is still // connected. // check for sockets that are read-ready ... if ((SOCKET_FD_UNDEF == fd_Socket) || (SOCKET_FD_CLOSED == fd_Socket) || (SOCKET_FD_DESTROYED == fd_Socket)) return; if (true == FD_ISSET (fd_Socket, &fsReadReady)) { // OnData is a virtual method overloaded by // ServerSocket to accept incomming socket // connections ... OnData (); } // check for sockets that are write-ready ... if ((SOCKET_FD_UNDEF == fd_Socket) || (SOCKET_FD_CLOSED == fd_Socket) || (SOCKET_FD_DESTROYED == fd_Socket)) return; if (true == FD_ISSET (fd_Socket, &fsWriteReady)) { if (Socket::Connected == e_ConnectionStatus) OnCanSend (); else if (Socket::InProgress == e_ConnectionStatus) { int iOptionValue = -1; socklen_t iOptionLength = sizeof (iOptionLength); if (0 != getsockopt (fd_Socket, SOL_SOCKET, SO_ERROR, &iOptionValue, &iOptionLength)) { String sError (strerror (errno)); cerr << "[ERROR] getsockopt returned error when checking " "socket connection in progress: " << sError << endl; } if (0 == iOptionValue) { e_ConnectionStatus = Socket::Connected; OnConnect (); } else { String sError (strerror (iOptionValue)); cerr << "[ERROR] Error on socket in connection progress: " << sError << endl; } } else { cerr << "[WARNING] Received write-ready notification on socket " "that is not connected." << endl; OnError (); // abort (); } } // check for sockets that are in error ... if ((SOCKET_FD_UNDEF == fd_Socket) || (SOCKET_FD_CLOSED == fd_Socket) || (SOCKET_FD_DESTROYED == fd_Socket)) return; if (true == FD_ISSET (fd_Socket, &fsError)) { if (EINTR != errno) { String sError (strerror (errno)); cerr << "[WARNING] Socket in error list. " << sError << endl; OnError (); } } FD_ZERO (&fsReadReady); FD_ZERO (&fsWriteReady); FD_ZERO (&fsError); }
CAudioSpecificConfig::CAudioSpecificConfig(void* buf ) { OnData(buf); }