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

📄 win32socketserver.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
📖 第 1 页 / 共 2 页
字号:
#include "byteorder.h"#include "common.h"#include "logging.h"#include "winping.h"#include "win32socketserver.h"#include "win32window.h"#include <ws2tcpip.h>namespace utils_base {///////////////////////////////////////////////////////////////////////////////// Win32Socket///////////////////////////////////////////////////////////////////////////////static const int kfRead  = 0x0001;static const int kfWrite = 0x0002;// Standard MTUsstatic const 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};static const uint32 IP_HEADER_SIZE = 20;static const uint32 ICMP_HEADER_SIZE = 8;#ifdef DEBUGLPCSTR WSAErrorToString(int error, LPCSTR *description_result) {  LPCSTR string = "Unspecified";  LPCSTR description = "Unspecified description";  switch (error) {    case ERROR_SUCCESS:      string = "SUCCESS";      description = "Operation succeeded";      break;    case WSAEWOULDBLOCK:      string = "WSAEWOULDBLOCK";      description = "Using a non-blocking socket, will notify later";      break;    case WSAEACCES:      string = "WSAEACCES";      description = "Access denied, or sharing violation";      break;    case WSAEADDRNOTAVAIL:      string = "WSAEADDRNOTAVAIL";      description = "Address is not valid in this context";      break;    case WSAENETDOWN:      string = "WSAENETDOWN";      description = "Network is down";      break;    case WSAENETUNREACH:      string = "WSAENETUNREACH";      description = "Network is up, but unreachable";      break;    case WSAENETRESET:      string = "WSANETRESET";      description = "Connection has been reset due to keep-alive activity";      break;    case WSAECONNABORTED:      string = "WSAECONNABORTED";      description = "Aborted by host";      break;    case WSAECONNRESET:      string = "WSAECONNRESET";      description = "Connection reset by host";      break;    case WSAETIMEDOUT:      string = "WSAETIMEDOUT";      description = "Timed out, host failed to respond";      break;    case WSAECONNREFUSED:      string = "WSAECONNREFUSED";      description = "Host actively refused connection";      break;    case WSAEHOSTDOWN:      string = "WSAEHOSTDOWN";      description = "Host is down";      break;    case WSAEHOSTUNREACH:      string = "WSAEHOSTUNREACH";      description = "Host is unreachable";      break;    case WSAHOST_NOT_FOUND:      string = "WSAHOST_NOT_FOUND";      description = "No such host is known";      break;  }  if (description_result) {    *description_result = description;  }  return string;}void ReportWSAError(LPCSTR context, int error, const sockaddr_in& addr) {  talk_base::SocketAddress address;  address.FromSockAddr(addr);  LPCSTR description_string;  LPCSTR error_string = WSAErrorToString(error, &description_string);  LOG(LS_INFO) << context << " = " << error    << " (" << error_string << ":" << description_string << ") ["    << address.ToString() << "]";}#elsevoid ReportWSAError(LPCSTR context, int error, const sockaddr_in& addr) { }#endif/////////////////////////////////////////////////////////////////////////////// Win32Socket::EventSink/////////////////////////////////////////////////////////////////////////////#define WM_SOCKETNOTIFY  (WM_USER + 50)#define WM_DNSNOTIFY     (WM_USER + 51)struct Win32Socket::DnsLookup {  HANDLE handle;  uint16 port;  char buffer[MAXGETHOSTSTRUCT];};class Win32Socket::EventSink : public Win32Window {public:  EventSink(Win32Socket * parent) : parent_(parent) { }  void Dispose();  virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,                         LRESULT& result);  virtual void OnFinalMessage(HWND hWnd);private:  bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result);  bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result);  Win32Socket * parent_;};voidWin32Socket::EventSink::Dispose() {  parent_ = NULL;  if (::IsWindow(handle())) {    ::DestroyWindow(handle());  } else {    delete this;  }}bool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,                                       LRESULT& result) {  switch (uMsg) {  case WM_SOCKETNOTIFY:  case WM_TIMER:    return OnSocketNotify(uMsg, wParam, lParam, result);  case WM_DNSNOTIFY:    return OnDnsNotify(wParam, lParam, result);  }  return false;}boolWin32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam,                                       LRESULT& result) {  result = 0;  // Make sure the socket isn't already closed  if (!parent_ || (parent_->socket_ == INVALID_SOCKET))    return true;  int event = WSAGETSELECTEVENT(lParam);  int wsa_error = WSAGETSELECTERROR(lParam);  if (uMsg == WM_TIMER) {    event = FD_CLOSE;    wsa_error = WSAETIMEDOUT;  } else if (event == FD_CLOSE) {    char ch;    if (::recv(parent_->socket_, &ch, 1, MSG_PEEK) > 0) {      parent_->signal_close_ = true;      return true;    }  }  parent_->OnSocketNotify(event, wsa_error);  return true;}boolWin32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam,                                    LRESULT& result) {  result = 0;  if (!parent_)    return true;  if (!parent_->dns_ ||     (parent_->dns_->handle != reinterpret_cast<HANDLE>(wParam))) {    ASSERT(false);      return true;  }  uint32 ip = 0;  int error = WSAGETASYNCERROR(lParam);  if (error == 0) {    hostent * pHost = reinterpret_cast<hostent *>(parent_->dns_->buffer);    uint32 net_ip = *reinterpret_cast<uint32 *>(pHost->h_addr_list[0]);    ip = utils_base::NetworkToHost32(net_ip);  }  parent_->OnDnsNotify(ip, error);  return true;}voidWin32Socket::EventSink::OnFinalMessage(HWND hWnd) {  delete this;}/////////////////////////////////////////////////////////////////////////////// Win32Socket/////////////////////////////////////////////////////////////////////////////Win32Socket::Win32Socket()  : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED),    signal_close_(false), sink_(NULL), dns_(NULL) {  // TODO: replace addr_ with SocketAddress  memset(&addr_, 0, sizeof(addr_));}Win32Socket::~Win32Socket() {  Close();}intWin32Socket::Attach(SOCKET s) {  ASSERT(socket_ == INVALID_SOCKET);  if (socket_ != INVALID_SOCKET)    return SOCKET_ERROR;  ASSERT(s != INVALID_SOCKET);  if (s == INVALID_SOCKET)    return SOCKET_ERROR;  socket_ = s;  state_ = CS_CONNECTED;  if (!Create(FD_READ | FD_WRITE | FD_CLOSE))    return SOCKET_ERROR;  return 0;}voidWin32Socket::SetTimeout(int ms) {  if (sink_)     ::SetTimer(sink_->handle(), 1, ms, 0);}utils_base::SocketAddressWin32Socket::GetLocalAddress() const {  sockaddr_in addr;  socklen_t addrlen = sizeof(addr);  int result = ::getsockname(socket_, (sockaddr*)&addr, &addrlen);  ASSERT(addrlen == sizeof(addr));  utils_base::SocketAddress address;  if (result >= 0) {    address.FromSockAddr(addr);  } else {    ASSERT(result >= 0);  }  return address;}utils_base::SocketAddress Win32Socket::GetRemoteAddress() const {  sockaddr_in addr;  socklen_t addrlen = sizeof(addr);  int result = ::getpeername(socket_, (sockaddr*)&addr, &addrlen);  ASSERT(addrlen == sizeof(addr));  utils_base::SocketAddress address;  if (result >= 0) {    address.FromSockAddr(addr);  } else {    ASSERT(errno == ENOTCONN);  }  return address;}intWin32Socket::Bind(const utils_base::SocketAddress& addr) {  ASSERT(socket_ == INVALID_SOCKET);  if (socket_ != INVALID_SOCKET)    return SOCKET_ERROR;  if (!Create(FD_ACCEPT | FD_CLOSE))    return SOCKET_ERROR;  sockaddr_in saddr;  addr.ToSockAddr(&saddr);  int err = ::bind(socket_, (sockaddr*)&saddr, sizeof(saddr));  UpdateLastError();  return err;}intWin32Socket::Connect(const utils_base::SocketAddress& addr) {  ASSERT(socket_ == INVALID_SOCKET);  if (socket_ != INVALID_SOCKET)    return SOCKET_ERROR;  if (!Create(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE))    return SOCKET_ERROR;  if (!addr.IsUnresolved()) {    sockaddr_in saddr;    addr.ToSockAddr(&saddr);    // now connect    return DoConnect(saddr);  }  LOG_F(LS_INFO) << "async dns lookup (" << addr.IPAsString() << ")";  DnsLookup * dns = new DnsLookup;  dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY,        addr.IPAsString().c_str(), dns->buffer, sizeof(dns->buffer));  if (!dns->handle) {    LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError();    delete dns;    UpdateLastError();    Close();    return SOCKET_ERROR;  }  dns->port = addr.port();  dns_ = dns;  state_ = CS_CONNECTING;  return 0;}intWin32Socket::DoConnect(const sockaddr_in& addr) {  connect_time_ = utils_base::GetMillisecondCount();  int result = connect(socket_, (SOCKADDR*)&addr, sizeof(addr));  if (result == SOCKET_ERROR) {    int code = WSAGetLastError();    if (code != WSAEWOULDBLOCK) {      ReportWSAError("WSAAsync:connect", code, addr);      error_ = code;      Close();      return SOCKET_ERROR;    }  }  addr_ = addr;

⌨️ 快捷键说明

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