예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #5
0
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;
}
예제 #6
0
 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()));
     });
 }
예제 #7
0
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);
		}
	}
}
예제 #8
0
// 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&)));
}
예제 #10
0
// 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;
}
예제 #11
0
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;
	}
}
예제 #12
0
    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);
        });

    }
예제 #13
0
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;
	}
}
예제 #14
0
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);
            }
        }
    }
}
예제 #15
0
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);
	}
}
예제 #16
0
파일: ASyncTCP.cpp 프로젝트: 4ib3r/domoticz
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();
	}
}
예제 #17
0
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
}
예제 #19
0
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;
	}
}
예제 #20
0
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;
}
예제 #21
0
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;
	}
}
예제 #22
0
// 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;
}
예제 #23
0
// 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);
}