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

📄 socket.cxx

📁 这是国外的resip协议栈
💻 CXX
字号:
/* * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org) * All Rights Reserved *  * 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. Neither the name of the Author nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 * OR CONTRIBUTORS 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. *//** @file * This file contains the implementation for the Netxx::Socket class along * with some helper functions.**/// common header#include "common.h"// Netxx includes#include "Socket.h"#include "Netxx/Timeout.h"#include "OSError.h"// system includes#if defined(WIN32)# include <winbase.h># include <winsock2.h>#else# include <errno.h># include <sys/types.h># include <sys/socket.h># include <sys/uio.h># include <sys/time.h># include <unistd.h>#endif// standard includes#include <algorithm>#include <string>#include <cstring>#include <cstdio>//####################################################################namespace {    void get_domain_and_type (Netxx::Socket::Type stype, int &domain, int &type);}//####################################################################Netxx::Socket::Socket (void)    : socketfd_(-1), probe_ready_(false), type_ready_(false){#   if defined(WIN32)	WSADATA wsdata;		if (WSAStartup(MAKEWORD(2,2), &wsdata) != 0) {	    throw Exception("failed to load WinSock");	}#   endif}//####################################################################Netxx::Socket::Socket (Type type)    : socketfd_(-1), probe_ready_(false), type_ready_(true), type_(type){#   if defined(WIN32)	WSADATA wsdata;		if (WSAStartup(MAKEWORD(2,2), &wsdata) != 0) {	    throw Exception("failed to load WinSock");	}#   endif    int socket_domain=0;    socket_type socket_type=0, socket_fd=0;    get_domain_and_type(type, socket_domain, socket_type);    if ( (socket_fd = socket(socket_domain, socket_type, 0)) < 0) {	std::string error("failure from socket(2): ");	error += strerror(get_last_error());	throw Exception(error);    }    socketfd_ = socket_fd;}//####################################################################Netxx::Socket::Socket (int socketfd)    : socketfd_(socketfd), probe_ready_(false), type_ready_(false){#   if defined(WIN32)	WSADATA wsdata;		if (WSAStartup(MAKEWORD(2,2), &wsdata) != 0) {	    throw Exception("failed to load WinSock");	}#   endif}//####################################################################Netxx::Socket::Socket (const Socket &other)     : probe_ready_(false), type_ready_(other.type_ready_), type_(other.type_){    if (other.socketfd_ != -1) {	socket_type dup_socket;#	if defined(WIN32)	    WSADATA wsdata;	    	    if (WSAStartup(MAKEWORD(2,2), &wsdata) != 0)		throw Exception("failed to load WinSock");	    WSAPROTOCOL_INFO proto_info;	    std::memset(&proto_info, 0, sizeof(proto_info));	    if (WSADuplicateSocket(other.socketfd_, GetCurrentProcessId(), &proto_info)) {		throw Exception("failed to duplicate socket");	    }	    	    if ( (dup_socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,		    FROM_PROTOCOL_INFO, &proto_info, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)	    {		throw Exception("failed to init duplicated socket");	    }#	else	    dup_socket = dup(other.socketfd_);	    if (dup_socket < 0) {		std::string error("dup(2) call failed: ");		error += strerror(get_last_error());		throw Exception(error);	    }#	endif	socketfd_ = dup_socket;    } else {	socketfd_ = -1;    }}//####################################################################Netxx::Socket& Netxx::Socket::operator= (const Socket &other) {    Socket tmp(other); swap(tmp);    return *this;}//####################################################################void Netxx::Socket::swap (Socket &other) {    std::swap(socketfd_, other.socketfd_);    std::swap(type_ready_, other.type_ready_);    std::swap(type_, other.type_);    probe_ready_ = other.probe_ready_ = false;    probe_.clear(); other.probe_.clear();}//####################################################################Netxx::Socket::~Socket (void) {    close();#   if defined(WIN32)	WSACleanup();#   endif}//####################################################################Netxx::signed_size_type Netxx::Socket::write (const void *buffer, size_type length, const Timeout &timeout) {    const char *buffer_ptr = static_cast<const char*>(buffer);    signed_size_type rc, bytes_written=0;    while (length) {	if (timeout && !writable(timeout)) return -1;	if ( (rc = send(socketfd_, buffer_ptr, length, 0)) < 0) {	    error_type error_code = get_last_error();	    if (error_code == EWOULDBLOCK) error_code = EAGAIN;	    switch (error_code) {		case EPIPE:		case ECONNRESET:		    return 0;		case EINTR:		    continue;		case EAGAIN:		    return -1;#if defined(WIN32)		case WSAENETRESET:		case WSAESHUTDOWN:		case WSAEHOSTUNREACH:		case WSAECONNABORTED:		case WSAETIMEDOUT:		    return 0;#endif		default:		{		    std::string error("send failed: ");		    error += strerror(error_code);		    throw Exception(error);		}	    }	}	buffer_ptr    += rc;	bytes_written += rc;	length        -= rc;    }    return bytes_written;}//####################################################################Netxx::signed_size_type Netxx::Socket::read (void *buffer, size_type length, const Timeout &timeout) {    signed_size_type rc;#   if defined(WIN32)	char *buffer_ptr = static_cast<char*>(buffer);#   else	void *buffer_ptr(buffer);#   endif    for (;;) {	if (timeout && !readable(timeout)) return -1;	if ( (rc = recv(socketfd_, buffer_ptr, length, 0)) < 0) {	    error_type error_code = get_last_error();	    if (error_code == EWOULDBLOCK) error_code = EAGAIN;	    switch (error_code) {		case ECONNRESET:		    return 0;		case EINTR:		    continue;		case EAGAIN:		    return -1;#if defined(WIN32)		case WSAEMSGSIZE:		    return length;		case WSAENETRESET:		case WSAESHUTDOWN:		case WSAECONNABORTED:		case WSAETIMEDOUT: // FIXME should this be return -1?		    return 0;#endif		default:		{		    std::string error("recv failure: ");		    error += strerror(error_code);		    throw Exception(error);		}	    }	}	break;    }    return rc;}//####################################################################bool Netxx::Socket::readable (const Timeout &timeout) {    if (!probe_ready_) {	probe_.add(socketfd_);	probe_ready_ = true;    }    Probe_impl::probe_type pt = probe_.probe(timeout, Probe::ready_read);    if (pt.empty()) return false;    return true;}//####################################################################bool Netxx::Socket::writable (const Timeout &timeout) {    if (!probe_ready_) {	probe_.add(socketfd_);	probe_ready_ = true;    }    Probe_impl::probe_type pt = probe_.probe(timeout, Probe::ready_write);    if (pt.empty()) return false;    return true;}//####################################################################bool Netxx::Socket::readable_or_writable (const Timeout &timeout) {    if (!probe_ready_) {	probe_.add(socketfd_);	probe_ready_ = true;    }    Probe_impl::probe_type pt = probe_.probe(timeout, Probe::ready_read|Probe::ready_write);    if (pt.empty()) return false;    return true;}//####################################################################void Netxx::Socket::close (void) {    if (socketfd_ != -1) {#	if defined(WIN32)	    closesocket(socketfd_);#	else	    ::close(socketfd_);#	endif	socketfd_ = -1;    }}//####################################################################void Netxx::Socket::release (void) {  socketfd_ = -1;}//####################################################################Netxx::Socket::Type Netxx::Socket::get_type (void) const {    if (!type_ready_) throw Exception("Netxx bug: Socket::get_type called when !type_ready_");    return type_;}//####################################################################int Netxx::Socket::get_socketfd (void) const {    return socketfd_;}//####################################################################void Netxx::Socket::set_socketfd (socket_type socketfd) {    close();    probe_ready_ = false;    socketfd_ = socketfd;    probe_.clear();}//####################################################################bool Netxx::Socket::operator! (void) const {    return socketfd_ == -1;}//####################################################################bool Netxx::Socket::operator< (const Socket &other) const {    return socketfd_ < other.socketfd_;}//####################################################################bool Netxx::Socket::operator< (socket_type socketfd) const {    return socketfd_ < socketfd;}//####################################################################bool Netxx::operator== (const Netxx::Socket &first, const Netxx::Socket &second) {    return first.get_socketfd() == second.get_socketfd();}//####################################################################bool Netxx::operator!= (const Netxx::Socket &first, const Netxx::Socket &second) {    return !(first == second);}//####################################################################namespace {    //####################################################################    void get_domain_and_type (Netxx::Socket::Type stype, int &domain, int &type) {	switch (stype) {	    case Netxx::Socket::TCP:		domain = PF_INET;		type	= SOCK_STREAM;		break;	    case Netxx::Socket::UDP:		domain	= PF_INET;		type	= SOCK_DGRAM;		break;#   ifndef NETXX_NO_INET6	    case Netxx::Socket::TCP6:		domain	= PF_INET6;		type	= SOCK_STREAM;		break;	    case Netxx::Socket::UDP6:		domain	= PF_INET6;		type	= SOCK_DGRAM;		break;#   endif#   ifndef WIN32	    case Netxx::Socket::LOCALSTREAM:		domain	= PF_LOCAL;		type	= SOCK_STREAM;		break;	    case Netxx::Socket::LOCALDGRAM:		domain	= PF_LOCAL;		type	= SOCK_DGRAM;		break;#   endif	    default:		domain = PF_INET;		type	= SOCK_STREAM;		break;	}    }    //####################################################################    } // end anonymous namespace

⌨️ 快捷键说明

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