/
zOMGdev
/
cppcms
Обзор
Документация
Войти
/
zOMGdev
/
cppcms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
booster/lib/aio/src/basic_socket.cpp
256 строк
5 KB
Artyom Beilis
Added support of snd/rcv buf options for socket
01 дек 2017, 17:46
01 дек 2017, 17:46
d85ace6
Код
Авторство
О чём код?
// // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh) // // 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) // #define BOOSTER_SOURCE #include "socket_details.h" #include <booster/aio/socket.h> //#define BOOSTER_AIO_FORCE_POLL namespace booster { namespace aio { struct basic_socket::data{}; basic_socket::basic_socket() { } basic_socket::basic_socket(io_service &srv) : basic_io_device(srv) { } basic_socket::~basic_socket() { } void basic_socket::open(family_type d,socket_type t,system::error_code &e) { int domain=0; switch(d) { case pf_unix: domain=AF_UNIX; break; case pf_inet: domain=AF_INET; break; case pf_inet6: domain = AF_INET6; break; } int type = 0; switch(t) { case sock_stream: type = SOCK_STREAM; break; case sock_datagram: type = SOCK_DGRAM; break; } { system::error_code etmp; close(etmp); } native_type fd = ::socket(domain,type,0); if(fd == invalid_socket) { e=geterror(); return; } assign(fd); } void basic_socket::open(family_type d,socket_type t) { system::error_code e; open(d,t,e); if(e) throw system::system_error(e); } endpoint basic_socket::local_endpoint(system::error_code &e) { std::vector<char> endpoint_raw_(1000,0); sockaddr *sa = reinterpret_cast<sockaddr *>(&endpoint_raw_.front()); socklen_t len = endpoint_raw_.size(); if(::getsockname(native(),sa,&len) < 0) e=geterror(); endpoint ep; ep.raw(sa,len); return ep; } endpoint basic_socket::local_endpoint() { system::error_code e; endpoint ep=local_endpoint(e); if(e) throw system::system_error(e); return ep; } endpoint basic_socket::remote_endpoint(system::error_code &e) { std::vector<char> endpoint_raw_(1000,0); sockaddr *sa = reinterpret_cast<sockaddr *>(&endpoint_raw_.front()); socklen_t len = endpoint_raw_.size(); endpoint ep; if(::getpeername(native(),sa,&len) < 0) e=geterror(); else ep.raw(sa,len); return ep; } endpoint basic_socket::remote_endpoint() { system::error_code e; endpoint ep=remote_endpoint(e); if(e) throw system::system_error(e); return ep; } void basic_socket::set_option(integer_option_type opt,int v,system::error_code &e) { int value = v; char const *p=reinterpret_cast<char const *>(&value); int res = 0; switch(opt) { case receive_buffer_size: res=::setsockopt(native(),SOL_SOCKET,SO_RCVBUF,p,sizeof(value)); break; case send_buffer_size: res=::setsockopt(native(),SOL_SOCKET,SO_SNDBUF,p,sizeof(value)); break; default: ; } if(res < 0) e=geterror(); } void basic_socket::set_option(integer_option_type opt,int v) { system::error_code e; set_option(opt,v,e); if(e) throw system::system_error(e); } int basic_socket::get_option(integer_option_type opt,system::error_code &e) { int value = 0; socklen_t len = sizeof(value); #ifdef BOOSTER_WIN32 char *ptr = reinterpret_cast<char *>(&value); #else int *ptr = &value; #endif int res = 0; switch(opt) { case receive_buffer_size: res=::getsockopt(native(),SOL_SOCKET,SO_RCVBUF,ptr,&len); break; case send_buffer_size: res=::getsockopt(native(),SOL_SOCKET,SO_SNDBUF,ptr,&len); break; default: ; } if(res < 0) { e=geterror(); return false; } return value; } int basic_socket::get_option(integer_option_type opt) { system::error_code e; int res = get_option(opt,e); if(e) throw system::system_error(e); return res; } void basic_socket::set_option(boolean_option_type opt,bool v,system::error_code &e) { int value = v ? 1 : 0; char const *p=reinterpret_cast<char const *>(&value); int res = 0; switch(opt) { case tcp_no_delay: res=::setsockopt(native(),IPPROTO_TCP,TCP_NODELAY,p,sizeof(value)); break; case keep_alive: res=::setsockopt(native(),SOL_SOCKET,SO_KEEPALIVE,p,sizeof(value)); break; case reuse_address: res=::setsockopt(native(),SOL_SOCKET,SO_REUSEADDR,p,sizeof(value)); break; default: ; } if(res < 0) e=geterror(); } void basic_socket::set_option(boolean_option_type opt,bool v) { system::error_code e; set_option(opt,v,e); if(e) throw system::system_error(e); } bool basic_socket::get_option(boolean_option_type opt,system::error_code &e) { int value = 0; socklen_t len = sizeof(value); #ifdef BOOSTER_WIN32 char *ptr = reinterpret_cast<char *>(&value); #else int *ptr = &value; #endif int res = 0; switch(opt) { case tcp_no_delay: res=::getsockopt(native(),IPPROTO_TCP,TCP_NODELAY,ptr,&len); break; case keep_alive: res=::getsockopt(native(),SOL_SOCKET,SO_KEEPALIVE,ptr,&len); break; case reuse_address: res=::getsockopt(native(),SOL_SOCKET,SO_REUSEADDR,ptr,&len); break; default: ; } if(res < 0) { e=geterror(); return false; } return value!=0; } bool basic_socket::get_option(boolean_option_type opt) { system::error_code e; bool res = get_option(opt,e); if(e) throw system::system_error(e); return res; } void basic_socket::bind(endpoint const &ep,system::error_code &e) { endpoint::native_address_type address = ep.raw(); if(::bind(native(),address.first,address.second) < 0) e=geterror(); } void basic_socket::bind(endpoint const &ep) { system::error_code e; bind(ep,e); if(e) throw system::system_error(e); } } // aio } // booster