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

📄 cfsocket.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:       src/mac/carbon/cfsocket.cpp// Purpose:    Socket handler classes// Authors:    Guilhem Lavaux, Guillermo Rodriguez Garcia// Created:    April 1997// Copyright:  (C) 1999-1997, Guilhem Lavaux//             (C) 2000-1999, Guillermo Rodriguez Garcia// RCS_ID:     $Id: cfsocket.cpp,v 1.16 2006/08/31 19:30:43 ABX Exp $// License:    see wxWindows licence/////////////////////////////////////////////////////////////////////////////#include "wx/wxprec.h"#ifdef __BORLANDC__    #pragma hdrstop#endif#if wxUSE_SOCKETS#include "wx/socket.h"#ifndef WX_PRECOMP    #include "wx/object.h"    #include "wx/string.h"    #include "wx/intl.h"    #include "wx/log.h"    #include "wx/event.h"    #include "wx/app.h"    #include "wx/utils.h"    #include "wx/timer.h"    #include "wx/module.h"#endif#include "wx/apptrait.h"#include "wx/sckaddr.h"#include "wx/mac/carbon/private.h"#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#define HAVE_INET_ATON// DLL options compatibility check:#include "wx/build.h"WX_CHECK_BUILD_OPTIONS("wxNet")// discard buffer#define MAX_DISCARD_SIZE (10 * 1024)#ifndef INVALID_SOCKET#define INVALID_SOCKET -1#endif// what to do within waits: we have 2 cases: from the main thread itself we// have to call wxYield() to let the events (including the GUI events and the// low-level (not wxWidgets) events from GSocket) be processed. From another// thread it is enough to just call wxThread::Yield() which will give away the// rest of our time slice: the explanation is that the events will be processed// by the main thread anyhow, without calling wxYield(), but we don't want to// eat the CPU time uselessly while sitting in the loop waiting for the data#if wxUSE_THREADS    #define PROCESS_EVENTS()        \    {                               \        if ( wxThread::IsMain() )   \            wxYield();              \        else                        \            wxThread::Yield();      \    }#else // !wxUSE_THREADS    #define PROCESS_EVENTS() wxYield()#endif // wxUSE_THREADS/!wxUSE_THREADS#define wxTRACE_Socket _T("wxSocket")IMPLEMENT_CLASS(wxSocketBase, wxObject)IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)// --------------------------------------------------------------------------// private classes// --------------------------------------------------------------------------class wxSocketState : public wxObject{public:  wxSocketFlags            m_flags;  wxSocketEventFlags       m_eventmask;  bool                     m_notify;  void                    *m_clientData;public:  wxSocketState() : wxObject() {}    DECLARE_NO_COPY_CLASS(wxSocketState)};struct _GSocket{  CFSocketNativeHandle m_fd;  GAddress *m_local;  GAddress *m_peer;  GSocketError m_error;  int m_non_blocking;  int m_server;  int m_stream;  int m_oriented;  int m_establishing;  unsigned long m_timeout;  // Callbacks  GSocketEventFlags m_detected;  GSocketCallback m_cbacks[GSOCK_MAX_EVENT];  char *m_data[GSOCK_MAX_EVENT];  CFSocketRef           m_cfSocket;  CFRunLoopSourceRef    m_runLoopSource;  CFReadStreamRef       m_readStream ;  CFWriteStreamRef      m_writeStream ;};struct _GAddress{  struct sockaddr *m_addr;  size_t m_len;  GAddressType m_family;  int m_realfamily;  GSocketError m_error;  int somethingElse ;};void wxMacCFSocketCallback(CFSocketRef s, CFSocketCallBackType callbackType,                         CFDataRef address, const void* data, void* info) ;void _GSocket_Enable(GSocket *socket, GSocketEvent event) ;void _GSocket_Disable(GSocket *socket, GSocketEvent event) ;// ==========================================================================// wxSocketBase// ==========================================================================// --------------------------------------------------------------------------// Initialization and shutdown// --------------------------------------------------------------------------// FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses//           to m_countInit with a crit sectionsize_t wxSocketBase::m_countInit = 0;bool wxSocketBase::IsInitialized(){    return m_countInit > 0;}bool wxSocketBase::Initialize(){    if ( !m_countInit++ )    {#if 0        wxAppTraits *traits = wxAppConsole::GetInstance() ?                              wxAppConsole::GetInstance()->GetTraits() : NULL;        GSocketGUIFunctionsTable *functions =            traits ? traits->GetSocketGUIFunctionsTable() : NULL;        GSocket_SetGUIFunctions(functions);        if ( !GSocket_Init() )        {            m_countInit--;            return false;        }#endif    }    return true;}void wxSocketBase::Shutdown(){    // we should be initialized    wxASSERT_MSG( m_countInit, wxT("extra call to Shutdown()") );    if ( !--m_countInit )    {#if 0        GSocket_Cleanup();#endif    }}// --------------------------------------------------------------------------// Ctor and dtor// --------------------------------------------------------------------------void wxSocketBase::Init(){  m_socket       = NULL;  m_type         = wxSOCKET_UNINIT;  // state  m_flags        = 0;  m_connected    =  m_establishing =  m_reading      =  m_writing      =  m_error        = false;  m_lcount       = 0;  m_timeout      = 600;  m_beingDeleted = false;  // pushback buffer  m_unread       = NULL;  m_unrd_size    = 0;  m_unrd_cur     = 0;  // events  m_id           = -1;  m_handler      = NULL;  m_clientData   = NULL;  m_notify       = false;  m_eventmask    = 0;  if ( !IsInitialized() )  {      // this Initialize() will be undone by wxSocketModule::OnExit(), all the      // other calls to it should be matched by a call to Shutdown()      Initialize();  }}wxSocketBase::wxSocketBase(){  Init();}wxSocketBase::wxSocketBase( wxSocketFlags flags, wxSocketType type){  Init();  m_flags = flags;  m_type  = type;}wxSocketBase::~wxSocketBase(){  // Just in case the app called Destroy() *and* then deleted  // the socket immediately: don't leave dangling pointers.  wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;  if ( traits )      traits->RemoveFromPendingDelete(this);  // Shutdown and close the socket  if (!m_beingDeleted)    Close();  // Destroy the GSocket object  if (m_socket)  {    GSocket_destroy(m_socket);  }  // Free the pushback buffer  if (m_unread)    free(m_unread);}bool wxSocketBase::Destroy(){  // Delayed destruction: the socket will be deleted during the next  // idle loop iteration. This ensures that all pending events have  // been processed.  m_beingDeleted = true;  // Shutdown and close the socket  Close();  // Supress events from now on  Notify(false);  // schedule this object for deletion  wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;  if ( traits )  {      // let the traits object decide what to do with us      traits->ScheduleForDestroy(this);  }  else // no app or no traits  {      // in wxBase we might have no app object at all, don't leak memory      delete this;  }  return true;}// --------------------------------------------------------------------------// Basic IO calls// --------------------------------------------------------------------------// The following IO operations update m_error and m_lcount:// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}//// TODO: Should Connect, Accept and AcceptWith update m_error?bool wxSocketBase::Close(){  // Interrupt pending waits  InterruptWait();  if (m_socket)    GSocket_Shutdown(m_socket);  m_connected = false;  m_establishing = false;  return true;}wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes){  // Mask read events  m_reading = true;  m_lcount = _Read(buffer, nbytes);  // If in wxSOCKET_WAITALL mode, all bytes should have been read.  if (m_flags & wxSOCKET_WAITALL)    m_error = (m_lcount != nbytes);  else    m_error = (m_lcount == 0);  // Allow read events from now on  m_reading = false;  return *this;}wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes){  int total = 0;  // Try the pushback buffer first  total = GetPushback(buffer, nbytes, false);  nbytes -= total;  buffer  = (char *)buffer + total;  // Return now in one of the following cases:  // - the socket is invalid,  // - we got all the data,  // - we got *some* data and we are not using wxSOCKET_WAITALL.  if ( !m_socket ||       !nbytes ||       ((total != 0) && !(m_flags & wxSOCKET_WAITALL)) )    return total;  // Possible combinations (they are checked in this order)  // wxSOCKET_NOWAIT  // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)  // wxSOCKET_BLOCK  // wxSOCKET_NONE  //  int ret;  if (m_flags & wxSOCKET_NOWAIT)  {    GSocket_SetNonBlocking(m_socket, 1);    ret = GSocket_Read(m_socket, (char *)buffer, nbytes);    GSocket_SetNonBlocking(m_socket, 0);    if (ret > 0)      total += ret;  }  else  {    bool more = true;    while (more)    {      if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )        break;      ret = GSocket_Read(m_socket, (char *)buffer, nbytes);      if (ret > 0)      {        total  += ret;        nbytes -= ret;        buffer  = (char *)buffer + ret;      }      // If we got here and wxSOCKET_WAITALL is not set, we can leave      // now. Otherwise, wait until we recv all the data or until there      // is an error.      //      more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));    }  }  return total;}wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes){  wxUint32 len, len2, sig, total;  bool error;  int old_flags;  struct  {    unsigned char sig[4];    unsigned char len[4];  }  msg;  // Mask read events  m_reading = true;  total = 0;  error = true;  old_flags = m_flags;  SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);  if (_Read(&msg, sizeof(msg)) != sizeof(msg))    goto exit;  sig = (wxUint32)msg.sig[0];  sig |= (wxUint32)(msg.sig[1] << 8);  sig |= (wxUint32)(msg.sig[2] << 16);  sig |= (wxUint32)(msg.sig[3] << 24);  if (sig != 0xfeeddead)  {    wxLogWarning( wxT("wxSocket: invalid signature in ReadMsg.") );    goto exit;  }  len = (wxUint32)msg.len[0];  len |= (wxUint32)(msg.len[1] << 8);  len |= (wxUint32)(msg.len[2] << 16);  len |= (wxUint32)(msg.len[3] << 24);  if (len > nbytes)  {    len2 = len - nbytes;    len = nbytes;  }  else    len2 = 0;  // Don't attemp to read if the msg was zero bytes long.  if (len)  {    total = _Read(buffer, len);    if (total != len)      goto exit;  }  if (len2)  {    char *discard_buffer = new char[MAX_DISCARD_SIZE];    long discard_len;    // NOTE: discarded bytes don't add to m_lcount.    do    {      discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);      discard_len = _Read(discard_buffer, (wxUint32)discard_len);      len2 -= (wxUint32)discard_len;    }    while ((discard_len > 0) && len2);    delete [] discard_buffer;    if (len2 != 0)      goto exit;  }  if (_Read(&msg, sizeof(msg)) != sizeof(msg))    goto exit;  sig = (wxUint32)msg.sig[0];  sig |= (wxUint32)(msg.sig[1] << 8);  sig |= (wxUint32)(msg.sig[2] << 16);  sig |= (wxUint32)(msg.sig[3] << 24);  if (sig != 0xdeadfeed)  {    wxLogWarning( wxT("wxSocket: invalid signature in ReadMsg.") );    goto exit;  }  // everything was OK  error = false;exit:  m_error = error;  m_lcount = total;  m_reading = false;  SetFlags(old_flags);  return *this;}wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes){  // Mask read events  m_reading = true;  m_lcount = _Read(buffer, nbytes);  Pushback(buffer, m_lcount);  // If in wxSOCKET_WAITALL mode, all bytes should have been read.  if (m_flags & wxSOCKET_WAITALL)    m_error = (m_lcount != nbytes);  else    m_error = (m_lcount == 0);  // Allow read events again  m_reading = false;  return *this;}wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes){  // Mask write events  m_writing = true;  m_lcount = _Write(buffer, nbytes);  // If in wxSOCKET_WAITALL mode, all bytes should have been written.  if (m_flags & wxSOCKET_WAITALL)    m_error = (m_lcount != nbytes);  else    m_error = (m_lcount == 0);  // Allow write events again  m_writing = false;  return *this;}wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes){  wxUint32 total = 0;  // If the socket is invalid or parameters are ill, return immediately  if (!m_socket || !buffer || !nbytes)    return 0;  // Possible combinations (they are checked in this order)  // wxSOCKET_NOWAIT  // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)  // wxSOCKET_BLOCK  // wxSOCKET_NONE  //  int ret;  if (m_flags & wxSOCKET_NOWAIT)  {    GSocket_SetNonBlocking(m_socket, 1);    ret = GSocket_Write(m_socket, (const char *)buffer, nbytes);    GSocket_SetNonBlocking(m_socket, 0);    if (ret > 0)      total = ret;  }  else  {    bool more = true;    while (more)

⌨️ 快捷键说明

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