⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfsocket.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {      if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )        break;      ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);      if (ret > 0)      {        total  += ret;        nbytes -= ret;        buffer  = (const char *)buffer + ret;      }      // If we got here and wxSOCKET_WAITALL is not set, we can leave      // now. Otherwise, wait until we send all the data or until there      // is an error.      //      more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));    }  }  return total;}wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes){  wxUint32 total;  bool error;  struct  {    unsigned char sig[4];    unsigned char len[4];  }  msg;  // Mask write events  m_writing = true;  error = true;  total = 0;  SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);  msg.sig[0] = (unsigned char) 0xad;  msg.sig[1] = (unsigned char) 0xde;  msg.sig[2] = (unsigned char) 0xed;  msg.sig[3] = (unsigned char) 0xfe;  msg.len[0] = (unsigned char) (nbytes & 0xff);  msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);  msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);  msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);  if (_Write(&msg, sizeof(msg)) < sizeof(msg))    goto exit;  total = _Write(buffer, nbytes);  if (total < nbytes)    goto exit;  msg.sig[0] = (unsigned char) 0xed;  msg.sig[1] = (unsigned char) 0xfe;  msg.sig[2] = (unsigned char) 0xad;  msg.sig[3] = (unsigned char) 0xde;  msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;  if ((_Write(&msg, sizeof(msg))) < sizeof(msg))    goto exit;  // everything was OK  error = false;exit:  m_error = error;  m_lcount = total;  m_writing = false;  return *this;}wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes){  if (nbytes != 0)    Pushback(buffer, nbytes);  m_error = false;  m_lcount = nbytes;  return *this;}wxSocketBase& wxSocketBase::Discard(){  char *buffer = new char[MAX_DISCARD_SIZE];  wxUint32 ret;  wxUint32 total = 0;  // Mask read events  m_reading = true;  SetFlags(wxSOCKET_NOWAIT);  do  {    ret = _Read(buffer, MAX_DISCARD_SIZE);    total += ret;  }  while (ret == MAX_DISCARD_SIZE);  delete[] buffer;  m_lcount = total;  m_error  = false;  // Allow read events again  m_reading = false;  return *this;}// --------------------------------------------------------------------------// Wait functions// --------------------------------------------------------------------------// All Wait functions poll the socket using GSocket_Select() to// check for the specified combination of conditions, until one// of these conditions become true, an error occurs, or the// timeout elapses. The polling loop calls PROCESS_EVENTS(), so// this won't block the GUI.bool wxSocketBase::_Wait(long seconds,                         long milliseconds,                         wxSocketEventFlags flags){  GSocketEventFlags result;  long timeout;  // Set this to true to interrupt ongoing waits  m_interrupt = false;  // Check for valid socket  if (!m_socket)    return false;  // Check for valid timeout value.  if (seconds != -1)    timeout = seconds * 1000 + milliseconds;  else    timeout = m_timeout * 1000;#if !defined(wxUSE_GUI) || !wxUSE_GUI  GSocket_SetTimeout(m_socket, timeout);#endif  // Wait in an active polling loop.  //  // NOTE: We duplicate some of the code in OnRequest, but this doesn't  //   hurt. It has to be here because the (GSocket) event might arrive  //   a bit delayed, and it has to be in OnRequest as well because we  //   don't know whether the Wait functions are being used.  //  // Do this at least once (important if timeout == 0, when  // we are just polling). Also, if just polling, do not yield.  wxStopWatch chrono;  bool done = false;  while (!done)  {    result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);    // Incoming connection (server) or connection established (client)    if (result & GSOCK_CONNECTION_FLAG)    {      m_connected = true;      m_establishing = false;      return true;    }    // Data available or output buffer ready    if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))    {      return true;    }    // Connection lost    if (result & GSOCK_LOST_FLAG)    {      m_connected = false;      m_establishing = false;      return (flags & GSOCK_LOST_FLAG) != 0;    }    // Wait more?    if ((!timeout) || (chrono.Time() > timeout) || (m_interrupt))      done = true;    else      PROCESS_EVENTS();  }  return false;}bool wxSocketBase::Wait(long seconds, long milliseconds){  return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |                                      GSOCK_OUTPUT_FLAG |                                      GSOCK_CONNECTION_FLAG |                                      GSOCK_LOST_FLAG);}bool wxSocketBase::WaitForRead(long seconds, long milliseconds){  // Check pushback buffer before entering _Wait  if (m_unread)    return true;  // Note that GSOCK_INPUT_LOST has to be explicitly passed to  // _Wait becuase of the semantics of WaitForRead: a return  // value of true means that a GSocket_Read call will return  // immediately, not that there is actually data to read.  return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);}bool wxSocketBase::WaitForWrite(long seconds, long milliseconds){  return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);}bool wxSocketBase::WaitForLost(long seconds, long milliseconds){  return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);}// --------------------------------------------------------------------------// Miscellaneous// --------------------------------------------------------------------------//// Get local or peer address//bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const{  GAddress *peer;  if (!m_socket)    return false;  peer = GSocket_GetPeer(m_socket);    // copying a null address would just trigger an assert anyway  if (!peer)    return false;  addr_man.SetAddress(peer);  GAddress_destroy(peer);  return true;}bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const{#if 0  GAddress *local;  if (!m_socket)    return false;  local = GSocket_GetLocal(m_socket);  addr_man.SetAddress(local);  GAddress_destroy(local);#endif  return true;}//// Save and restore socket state//void wxSocketBase::SaveState(){  wxSocketState *state;  state = new wxSocketState();  state->m_flags      = m_flags;  state->m_notify     = m_notify;  state->m_eventmask  = m_eventmask;  state->m_clientData = m_clientData;  m_states.Append(state);}void wxSocketBase::RestoreState(){  wxList::compatibility_iterator node;  wxSocketState *state;  node = m_states.GetLast();  if (!node)    return;  state = (wxSocketState *)node->GetData();  m_flags      = state->m_flags;  m_notify     = state->m_notify;  m_eventmask  = state->m_eventmask;  m_clientData = state->m_clientData;  m_states.Erase(node);  delete state;}//// Timeout and flags//void wxSocketBase::SetTimeout(long seconds){  m_timeout = seconds;#if 0  if (m_socket)    GSocket_SetTimeout(m_socket, m_timeout * 1000);#endif}void wxSocketBase::SetFlags(wxSocketFlags flags){  m_flags = flags;}// --------------------------------------------------------------------------// Event handling// --------------------------------------------------------------------------// A note on how events are processed, which is probably the most// difficult thing to get working right while keeping the same API// and functionality for all platforms.//// When GSocket detects an event, it calls wx_socket_callback, which in// turn just calls wxSocketBase::OnRequest in the corresponding wxSocket// object. OnRequest does some housekeeping, and if the event is to be// propagated to the user, it creates a new wxSocketEvent object and// posts it. The event is not processed immediately, but delayed with// AddPendingEvent instead. This is necessary in order to decouple the// event processing from wx_socket_callback; otherwise, subsequent IO// calls made from the user event handler would fail, as gtk callbacks// are not reentrant.//// Note that, unlike events, user callbacks (now deprecated) are _not_// decoupled from wx_socket_callback and thus they suffer from a variety// of problems. Avoid them where possible and use events instead.extern "C"void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),                                    GSocketEvent notification,                                    char *cdata){  wxSocketBase *sckobj = (wxSocketBase *)cdata;  sckobj->OnRequest((wxSocketNotify) notification);}void wxSocketBase::OnRequest(wxSocketNotify notification){  // NOTE: We duplicate some of the code in _Wait, but this doesn't  // hurt. It has to be here because the (GSocket) event might arrive  // a bit delayed, and it has to be in _Wait as well because we don't  // know whether the Wait functions are being used.  switch (notification)  {    case wxSOCKET_CONNECTION:      m_establishing = false;      m_connected = true;      break;    // If we are in the middle of a R/W operation, do not    // propagate events to users. Also, filter 'late' events    // which are no longer valid.    case wxSOCKET_INPUT:      if (m_reading || !GSocket_Select(m_socket, GSOCK_INPUT_FLAG))        return;      break;    case wxSOCKET_OUTPUT:      if (m_writing || !GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))        return;      break;    case wxSOCKET_LOST:      m_connected = false;      m_establishing = false;      break;    default:      break;  }  // Schedule the event  wxSocketEventFlags flag = 0;  wxUnusedVar(flag);  switch (notification)  {    case GSOCK_INPUT:      flag = GSOCK_INPUT_FLAG;      break;    case GSOCK_OUTPUT:      flag = GSOCK_OUTPUT_FLAG;      break;    case GSOCK_CONNECTION:      flag = GSOCK_CONNECTION_FLAG;      break;    case GSOCK_LOST:      flag = GSOCK_LOST_FLAG;      break;    default:      wxLogWarning( wxT("wxSocket: unknown event!") );      return;  }  if (((m_eventmask & flag) == flag) && m_notify)  {    if (m_handler)    {      wxSocketEvent event(m_id);      event.m_event      = notification;      event.m_clientData = m_clientData;      event.SetEventObject(this);      m_handler->AddPendingEvent(event);    }  }}void wxSocketBase::Notify(bool notify){  m_notify = notify;}void wxSocketBase::SetNotify(wxSocketEventFlags flags){  m_eventmask = flags;}void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id){  m_handler = &handler;  m_id      = id;}// --------------------------------------------------------------------------// Pushback buffer// --------------------------------------------------------------------------void wxSocketBase::Pushback(const void *buffer, wxUint32 size){  if (!size)    return;  if (m_unread == NULL)    m_unread = malloc(size);  else  {    void *tmp;    tmp = malloc(m_unrd_size + size);    memcpy((char *)tmp + size, m_unread, m_unrd_size);    free(m_unread);    m_unread = tmp;  }  m_unrd_size += size;  memcpy(m_unread, buffer, size);}wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek){  if (!m_unrd_size)    return 0;  if (size > (m_unrd_size-m_unrd_cur))    size = m_unrd_size-m_unrd_cur;  memcpy(buffer, (char *)m_unread + m_unrd_cur, size);  if (!peek)  {    m_unrd_cur += size;    if (m_unrd_size == m_unrd_cur)    {      free(m_unread);      m_unread = NULL;      m_unrd_size = 0;      m_unrd_cur  = 0;    }  }  return size;}// ==========================================================================// wxSocketServer// ==========================================================================// --------------------------------------------------------------------------// Ctor// --------------------------------------------------------------------------wxSocketServer::wxSocketServer(wxSockAddress& addr_man,                               wxSocketFlags flags)              : wxSocketBase(flags, wxSOCKET_SERVER){    wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );    m_socket = GSocket_new();    if (!m_socket)    {        wxLogTrace( wxTRACE_Socket, wxT("*** GSocket_new failed") );        return;    }    // Setup the socket as server#if 0    GSocket_SetLocal(m_socket, addr_man.GetAddress());    if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)    {        GSocket_destroy(m_socket);        m_socket = NULL;        wxLogTrace( wxTRACE_Socket, wxT("*** GSocket_SetServer failed") );        return;    }    GSocket_SetTimeout(m_socket, m_timeout * 1000);    GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |                                  GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,                                  wx_socket_callback, (char *)this);#endif}// --------------------------------------------------------------------------// Accept// --------------------------------------------------------------------------bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait){  GSocket *child_socket;  if (!m_socket)    return false;  // If wait == false, then the call should be nonblocking.  // When we are finished, we put the socket to blocking mode  // again.#if 0  if (!wait)    GSocket_SetNonBlocking(m_socket, 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -