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

📄 socket_ops.hpp

📁 这是国外的resip协议栈
💻 HPP
📖 第 1 页 / 共 4 页
字号:
//// socket_ops.hpp// ~~~~~~~~~~~~~~//// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//#ifndef ASIO_DETAIL_SOCKET_OPS_HPP#define ASIO_DETAIL_SOCKET_OPS_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)#include "asio/detail/push_options.hpp"#include "asio/detail/push_options.hpp"#include <boost/config.hpp>#include <boost/assert.hpp>#include <cstdio>#include <cstdlib>#include <cstring>#include <cerrno>#include <boost/detail/workaround.hpp>#include <new>#include "asio/detail/pop_options.hpp"#include "asio/error.hpp"#include "asio/detail/socket_types.hpp"namespace asio {namespace detail {namespace socket_ops {#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)struct msghdr { int msg_namelen; };#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)#if defined(__hpux)// HP-UX doesn't declare these functions extern "C", so they are declared again// here to avoid linker errors about undefined symbols.extern "C" char* if_indextoname(unsigned int, char*);extern "C" unsigned int if_nametoindex(const char*);#endif // defined(__hpux)inline void clear_error(asio::error_code& ec){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  WSASetLastError(0);#else  errno = 0;#endif  ec = asio::error_code();}template <typename ReturnType>inline ReturnType error_wrapper(ReturnType return_value,    asio::error_code& ec){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  ec = asio::error_code(WSAGetLastError(),      asio::error::get_system_category());#else  ec = asio::error_code(errno,      asio::error::get_system_category());#endif  return return_value;}template <typename SockLenType>inline socket_type call_accept(SockLenType msghdr::*,    socket_type s, socket_addr_type* addr, std::size_t* addrlen){  SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;  socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);  if (addrlen)    *addrlen = (std::size_t)tmp_addrlen;  return result;}inline socket_type accept(socket_type s, socket_addr_type* addr,    std::size_t* addrlen, asio::error_code& ec){  clear_error(ec);  socket_type new_s = error_wrapper(call_accept(        &msghdr::msg_namelen, s, addr, addrlen), ec);  if (new_s == invalid_socket)    return new_s;#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)  int optval = 1;  int result = error_wrapper(::setsockopt(new_s,        SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);  if (result != 0)  {    ::close(new_s);    return invalid_socket;  }#endif#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  clear_error(ec);#endif  return new_s;}template <typename SockLenType>inline int call_bind(SockLenType msghdr::*,    socket_type s, const socket_addr_type* addr, std::size_t addrlen){  return ::bind(s, addr, (SockLenType)addrlen);}inline int bind(socket_type s, const socket_addr_type* addr,    std::size_t addrlen, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(call_bind(        &msghdr::msg_namelen, s, addr, addrlen), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}inline int close(socket_type s, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  int result = error_wrapper(::closesocket(s), ec);# if defined(UNDER_CE)  if (result == 0)    clear_error(ec);# endif  return result;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  return error_wrapper(::close(s), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int shutdown(socket_type s, int what, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(::shutdown(s, what), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}template <typename SockLenType>inline int call_connect(SockLenType msghdr::*,    socket_type s, const socket_addr_type* addr, std::size_t addrlen){  return ::connect(s, addr, (SockLenType)addrlen);}inline int connect(socket_type s, const socket_addr_type* addr,    std::size_t addrlen, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(call_connect(        &msghdr::msg_namelen, s, addr, addrlen), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}inline int listen(socket_type s, int backlog, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(::listen(s, backlog), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)typedef WSABUF buf;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)typedef iovec buf;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)inline void init_buf(buf& b, void* data, size_t size){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  b.buf = static_cast<char*>(data);  b.len = static_cast<u_long>(size);#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  b.iov_base = data;  b.iov_len = size;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline void init_buf(buf& b, const void* data, size_t size){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  b.buf = static_cast<char*>(const_cast<void*>(data));  b.len = static_cast<u_long>(size);#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  b.iov_base = const_cast<void*>(data);  b.iov_len = size;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr){  name = addr;}inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr){  name = const_cast<socket_addr_type*>(addr);}template <typename T>inline void init_msghdr_msg_name(T& name, socket_addr_type* addr){  name = reinterpret_cast<T>(addr);}template <typename T>inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr){  name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));}inline int recv(socket_type s, buf* bufs, size_t count, int flags,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  // Receive some data.  DWORD recv_buf_count = static_cast<DWORD>(count);  DWORD bytes_transferred = 0;  DWORD recv_flags = flags;  int result = error_wrapper(::WSARecv(s, bufs,        recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);  if (result != 0)    return -1;# if defined(UNDER_CE)  clear_error(ec);# endif  return bytes_transferred;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  msghdr msg = msghdr();  msg.msg_iov = bufs;  msg.msg_iovlen = count;  return error_wrapper(::recvmsg(s, &msg, flags), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,    socket_addr_type* addr, std::size_t* addrlen,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  // Receive some data.  DWORD recv_buf_count = static_cast<DWORD>(count);  DWORD bytes_transferred = 0;  DWORD recv_flags = flags;  int tmp_addrlen = (int)*addrlen;  int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,        &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);  *addrlen = (std::size_t)tmp_addrlen;  if (result != 0)    return -1;# if defined(UNDER_CE)  clear_error(ec);# endif  return bytes_transferred;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  msghdr msg = msghdr();  init_msghdr_msg_name(msg.msg_name, addr);  msg.msg_namelen = *addrlen;  msg.msg_iov = bufs;  msg.msg_iovlen = count;  int result = error_wrapper(::recvmsg(s, &msg, flags), ec);  *addrlen = msg.msg_namelen;  return result;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int send(socket_type s, const buf* bufs, size_t count, int flags,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  // Send the data.  DWORD send_buf_count = static_cast<DWORD>(count);  DWORD bytes_transferred = 0;  DWORD send_flags = flags;  int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs),        send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);  if (result != 0)    return -1;# if defined(UNDER_CE)  clear_error(ec);# endif  return bytes_transferred;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  msghdr msg = msghdr();  msg.msg_iov = const_cast<buf*>(bufs);  msg.msg_iovlen = count;#if defined(__linux__)  flags |= MSG_NOSIGNAL;#endif // defined(__linux__)  return error_wrapper(::sendmsg(s, &msg, flags), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,    const socket_addr_type* addr, std::size_t addrlen,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  // Send the data.  DWORD send_buf_count = static_cast<DWORD>(count);  DWORD bytes_transferred = 0;  int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),        send_buf_count, &bytes_transferred, flags, addr,        static_cast<int>(addrlen), 0, 0), ec);  if (result != 0)    return -1;# if defined(UNDER_CE)  clear_error(ec);# endif  return bytes_transferred;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  msghdr msg = msghdr();  init_msghdr_msg_name(msg.msg_name, addr);  msg.msg_namelen = addrlen;  msg.msg_iov = const_cast<buf*>(bufs);  msg.msg_iovlen = count;#if defined(__linux__)  flags |= MSG_NOSIGNAL;#endif // defined(__linux__)  return error_wrapper(::sendmsg(s, &msg, flags), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline socket_type socket(int af, int type, int protocol,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0,        WSA_FLAG_OVERLAPPED), ec);  if (s == invalid_socket)    return s;  if (af == AF_INET6)  {    // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to    // false. This will only succeed on Windows Vista and later versions of    // Windows, where a dual-stack IPv4/v6 implementation is available.    DWORD optval = 0;    ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,        reinterpret_cast<const char*>(&optval), sizeof(optval));  }# if defined(UNDER_CE)  clear_error(ec);# endif  return s;#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)  socket_type s = error_wrapper(::socket(af, type, protocol), ec);  if (s == invalid_socket)    return s;  int optval = 1;  int result = error_wrapper(::setsockopt(s,        SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);  if (result != 0)  {    ::close(s);    return invalid_socket;  }  return s;#else  return error_wrapper(::socket(af, type, protocol), ec);#endif}template <typename SockLenType>inline int call_setsockopt(SockLenType msghdr::*,    socket_type s, int level, int optname,    const void* optval, std::size_t optlen){  return ::setsockopt(s, level, optname,      (const char*)optval, (SockLenType)optlen);}inline int setsockopt(socket_type s, int level, int optname,    const void* optval, std::size_t optlen, asio::error_code& ec){  if (level == custom_socket_option_level && optname == always_fail_option)  {    ec = asio::error::invalid_argument;    return -1;  }#if defined(__BORLANDC__)  // Mysteriously, using the getsockopt and setsockopt functions directly with  // Borland C++ results in incorrect values being set and read. The bug can be  // worked around by using function addresses resolved with GetProcAddress.  if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))  {    typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);    if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))    {      clear_error(ec);      return error_wrapper(sso(s, level, optname,            reinterpret_cast<const char*>(optval),            static_cast<int>(optlen)), ec);    }  }  ec = asio::error::fault;  return -1;#else // defined(__BORLANDC__)  clear_error(ec);  int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,        s, level, optname, optval, optlen), ec);# if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);# endif  return result;#endif // defined(__BORLANDC__)}template <typename SockLenType>inline int call_getsockopt(SockLenType msghdr::*,    socket_type s, int level, int optname,    void* optval, std::size_t* optlen){  SockLenType tmp_optlen = (SockLenType)*optlen;  int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);  *optlen = (std::size_t)tmp_optlen;  return result;}inline int getsockopt(socket_type s, int level, int optname, void* optval,    size_t* optlen, asio::error_code& ec){  if (level == custom_socket_option_level && optname == always_fail_option)  {    ec = asio::error::invalid_argument;    return -1;  }#if defined(__BORLANDC__)  // Mysteriously, using the getsockopt and setsockopt functions directly with  // Borland C++ results in incorrect values being set and read. The bug can be  // worked around by using function addresses resolved with GetProcAddress.

⌨️ 快捷键说明

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