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

📄 physicalsocketserver.cxx

📁 由GOOGLE的JINGLE项目中移植的网络库
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* * libjingle * Copyright 2004--2005, Google Inc. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions are met: * *  1. Redistributions of source code must retain the above copyright notice,  *     this list of conditions and the following disclaimer. *  2. Redistributions in binary form must reproduce the above copyright notice, *     this list of conditions and the following disclaimer in the documentation *     and/or other materials provided with the distribution. *  3. The name of the author may not be used to endorse or promote products  *     derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#if defined(_MSC_VER) && _MSC_VER < 1300
#pragma warning(disable:4786 4530)
#endif#include <cassert>#include "basictypes.h"#include "byteorder.h"#include "common.h"#include "physicalsocketserver.h"#include "time.h"#include <winsock2.h>#include <ws2tcpip.h>#define _WINSOCKAPI_#include <windows.h>#undef SetPort#include <algorithm>class WinsockInitializer {public:  WinsockInitializer() {    WSADATA wsaData;    WORD wVersionRequested = MAKEWORD(1, 0);    err_ = WSAStartup(wVersionRequested, &wsaData);  }  ~WinsockInitializer() {    WSACleanup();  }  int error() {    return err_;  }private:  int err_;};WinsockInitializer g_winsockinit;namespace cricket {const int kfRead  = 0x0001;const int kfWrite = 0x0002;const int kfConnect = 0x0004;const int kfClose = 0x0008;// Standard MTUsconst uint16 PACKET_MAXIMUMS[] = {  65535,    // Theoretical maximum, Hyperchannel  32000,    // Nothing  17914,    // 16Mb IBM Token Ring  8166,     // IEEE 802.4  //4464,   // IEEE 802.5 (4Mb max)  4352,     // FDDI  //2048,   // Wideband Network  2002,     // IEEE 802.5 (4Mb recommended)  //1536,   // Expermental Ethernet Networks  //1500,   // Ethernet, Point-to-Point (default)  1492,     // IEEE 802.3  1006,     // SLIP, ARPANET  //576,    // X.25 Networks  //544,    // DEC IP Portal  //512,    // NETBIOS  508,      // IEEE 802/Source-Rt Bridge, ARCNET  296,      // Point-to-Point (low delay)  68,       // Official minimum  0,        // End of list marker};const uint32 IP_HEADER_SIZE = 20;const uint32 ICMP_HEADER_SIZE = 8;class PhysicalSocket : public AsyncSocket {public:  PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET)    : ss_(ss), s_(s), enabled_events_(0), error_(0),      state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED) {    if (s != INVALID_SOCKET)      enabled_events_ = kfRead | kfWrite;  }  virtual ~PhysicalSocket() {    Close();  }  // Creates the underlying OS socket (same as the "socket" function).  virtual bool Create(int type) {    Close();    s_ = ::socket(AF_INET, type, 0);    UpdateLastError();    enabled_events_ = kfRead | kfWrite;    return s_ != INVALID_SOCKET;  }  SocketAddress GetLocalAddress() const {    struct sockaddr_in addr;    socklen_t addrlen = sizeof(addr);    int result = ::getsockname(s_, (struct sockaddr*)&addr, &addrlen);    assert(addrlen == sizeof(addr));    if (result >= 0) {      return SocketAddress(NetworkToHost32(addr.sin_addr.s_addr),                           NetworkToHost16(addr.sin_port));    } else {      return SocketAddress();    }  }  SocketAddress GetRemoteAddress() const {    struct sockaddr_in addr;    socklen_t addrlen = sizeof(addr);    int result = ::getpeername(s_, (struct sockaddr*)&addr, &addrlen);    assert(addrlen == sizeof(addr));    if (result >= 0) {      return SocketAddress(          NetworkToHost32(addr.sin_addr.s_addr),          NetworkToHost16(addr.sin_port));    } else {      // assert(errno == ENOTCONN);      return SocketAddress();    }  }  int Bind(const SocketAddress& addr) {    struct sockaddr_in saddr;    IP2SA(&addr, &saddr);    int err = ::bind(s_, (struct sockaddr*)&saddr, sizeof(saddr));    UpdateLastError();    return err;  }  int Connect(const SocketAddress& addr) {    // TODO: Implicit creation is required to reconnect...    // ...but should we make it more explicit?    if ((s_ == INVALID_SOCKET) && !Create(SOCK_STREAM))      return SOCKET_ERROR;    SocketAddress addr2(addr);    if (addr2.IsUnresolved()) {           addr2.Resolve(); // TODO: Do this async later?    }    struct sockaddr_in saddr;    IP2SA(&addr2, &saddr);    int err = ::connect(s_, (struct sockaddr*)&saddr, sizeof(saddr));    UpdateLastError();    //LOG(INFO) << "SOCK[" << static_cast<int>(s_) << "] Connect(" << addr2.ToString() << ") Ret: " << err << " Error: " << error_;    if (err == 0) {      state_ = CS_CONNECTED;    } else if (IsBlockingError(error_)) {      state_ = CS_CONNECTING;      enabled_events_ |= kfConnect;    }    return err;  }  int GetError() const {    return error_;  }  void SetError(int error) {    error_ = error;  }  ConnState GetState() const {    return state_;  }  int SetOption(Option opt, int value) {    assert(opt == OPT_DONTFRAGMENT);
    value = (value == 0) ? 0 : 1;    return ::setsockopt(        s_, IPPROTO_IP, IP_DONTFRAGMENT, reinterpret_cast<char*>(&value),        sizeof(value));  }  int Send(const void *pv, size_t cb) {    int sent = ::send(s_, reinterpret_cast<const char *>(pv), (int)cb, 0);    UpdateLastError();    //LOG(INFO) << "SOCK[" << static_cast<int>(s_) << "] Send(" << cb << ") Ret: " << sent << " Error: " << error_;    ASSERT(sent <= static_cast<int>(cb));  // We have seen minidumps where this may be false    if ((sent < 0) && IsBlockingError(error_)) {      enabled_events_ |= kfWrite;    }    return sent;  }  int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {    struct sockaddr_in saddr;    IP2SA(&addr, &saddr);    int sent = ::sendto(        s_, (const char *)pv, (int)cb, 0, (struct sockaddr*)&saddr,        sizeof(saddr));    UpdateLastError();    ASSERT(sent <= static_cast<int>(cb));  // We have seen minidumps where this may be false    if ((sent < 0) && IsBlockingError(error_)) {      enabled_events_ |= kfWrite;    }    return sent;  }  int Recv(void *pv, size_t cb) {    int received = ::recv(s_, (char *)pv, (int)cb, 0);    if ((received == 0) && (cb != 0)) {      // Note: on graceful shutdown, recv can return 0.  In this case, we      // pretend it is blocking, and then signal close, so that simplifying      // assumptions can be made about Recv.      error_ = EWOULDBLOCK;      return SOCKET_ERROR;    }    UpdateLastError();    if ((received >= 0) || IsBlockingError(error_)) {      enabled_events_ |= kfRead;    }    return received;  }  int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {    struct sockaddr saddr;    socklen_t cbAddr = sizeof(saddr);    int received = ::recvfrom(s_, (char *)pv, (int)cb, 0, &saddr, &cbAddr);    UpdateLastError();    if ((received >= 0) && (paddr != NULL))      SA2IP(&saddr, paddr);    if ((received >= 0) || IsBlockingError(error_)) {      enabled_events_ |= kfRead;    }    return received;  }  int Listen(int backlog) {    int err = ::listen(s_, backlog);    UpdateLastError();    if (err == 0)      state_ = CS_CONNECTING;    return err;  }  Socket* Accept(SocketAddress *paddr) {    struct sockaddr saddr;    socklen_t cbAddr = sizeof(saddr);    SOCKET s = ::accept(s_, &saddr, &cbAddr);    UpdateLastError();    if (s == INVALID_SOCKET)      return NULL;    if (paddr != NULL)      SA2IP(&saddr, paddr);    return ss_->WrapSocket(s);  }  int Close() {    if (s_ == INVALID_SOCKET)      return 0;    int err = ::closesocket(s_);    UpdateLastError();    //LOG(INFO) << "SOCK[" << static_cast<int>(s_) << "] Close() Ret: " << err << " Error: " << error_;    s_ = INVALID_SOCKET;    state_ = CS_CLOSED;    enabled_events_ = 0;    return err;  }  int EstimateMTU(uint16* mtu) {    SocketAddress addr = GetRemoteAddress();    if (addr.IsAny()) {      error_ = ENOTCONN;      return -1;    }
    // TODO: no support
	return -1;  }  SocketServer* socketserver() { return ss_; } protected:  PhysicalSocketServer* ss_;  SOCKET s_;  uint32 enabled_events_;  int error_;  ConnState state_;  void UpdateLastError() {    error_ = WSAGetLastError();  }  void IP2SA(const SocketAddress *paddr, struct sockaddr_in *psaddr) {    memset(psaddr, 0, sizeof(*psaddr));    psaddr->sin_family = AF_INET;    psaddr->sin_port = HostToNetwork16(paddr->port());    if (paddr->ip() == 0)      psaddr->sin_addr.s_addr = INADDR_ANY;    else      psaddr->sin_addr.s_addr = HostToNetwork32(paddr->ip());  }  void SA2IP(const struct sockaddr *psaddr, SocketAddress *paddr) {    const struct sockaddr_in *psaddr_in =        reinterpret_cast<const struct sockaddr_in*>(psaddr);    paddr->SetIP(NetworkToHost32(psaddr_in->sin_addr.s_addr));    paddr->SetPort(NetworkToHost16(psaddr_in->sin_port));  }};class Dispatcher {public:  virtual uint32 GetRequestedEvents() = 0;  virtual void OnPreEvent(uint32 ff) = 0;    virtual void OnEvent(uint32 ff, int err) = 0;  virtual WSAEVENT GetWSAEvent() = 0;  virtual SOCKET GetSocket() = 0;  virtual bool CheckSignalClose() = 0;};uint32 FlagsToEvents(uint32 events) {  uint32 ffFD = FD_CLOSE | FD_ACCEPT;  if (events & kfRead)    ffFD |= FD_READ;  if (events & kfWrite)    ffFD |= FD_WRITE;  if (events & kfConnect)    ffFD |= FD_CONNECT;  return ffFD;}class EventDispatcher : public Dispatcher {public:  EventDispatcher(PhysicalSocketServer *ss) : ss_(ss) {    if (hev_ = WSACreateEvent()) {      ss_->Add(this);    }  }  ~EventDispatcher() {    if (hev_ != NULL) {      ss_->Remove(this);      WSACloseEvent(hev_);      hev_ = NULL;    }  }    virtual void Signal() {    if (hev_ != NULL)      WSASetEvent(hev_);  }    virtual uint32 GetRequestedEvents() {

⌨️ 快捷键说明

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