📄 socket.h
字号:
int_type in_avail()
{
unsigned long n;
if( s && ::ioctlsocket( s->sock, FIONREAD, &n ) != _Myt::invalid )
return n;
else
return 0;
}
// OPTION SETTING
bool shutdown( _Myt::shuthow sh ){
return s ? s->shutdown( sh ) : false;
}
bool _GetBufPtrs( _e** &ibeg, _e** &inext, streamsize* &icnt, _e** &obeg, _e** &onext, streamsize* &ocnt )
{
if( s )
{
ibeg = &s->ibeg; inext = &s->inext; icnt = &s->icnt;
obeg = &s->obeg; onext = &s->onext; ocnt = &s->ocnt;
}
return s != 0;
}
int getopt (int op, void* buf, int len, int level=sol_socket) const
{
if( ::getsockopt (sd(), level, op, (char*)buf, &len) != SOCKET_ERROR )
return len;
return 0;
}
bool setopt (int op, void* buf, int len, int level=sol_socket) const
{
return ::setsockopt (sd(), level, op, (char*) buf, len) != SOCKET_ERROR;
}
type gettype () const
{
int ty=0;
if( getopt (so_type, &ty, sizeof (ty)) )
return type(ty);
return type(invalid);
}
int clearerror () const
{
int err=0;
if( getopt (so_error, &err, sizeof (err)) )
return err;
return invalid;
}
bool debug () const
{
int old = 0;
getopt (so_debug, &old, sizeof (old));
return old==0;
}
bool debug (bool set) const
{
int old=0;
int opt = set?1:0;
if( getopt (so_debug, &old, sizeof (old)) )
setopt (so_debug, &opt, sizeof (opt));
return old==0;
}
bool reuseaddr () const
{
int old = 0;
getopt (so_reuseaddr, &old, sizeof (old));
return old==0;
}
bool reuseaddr (bool set) const
{
int old=0;
int opt = set?1:0;
getopt (so_reuseaddr, &old, sizeof (old));
setopt (so_reuseaddr, &opt, sizeof (opt));
return old==0;
}
bool keepalive () const
{
int old = 0;
getopt (so_keepalive, &old, sizeof (old));
return old==0;
}
bool keepalive (bool set) const
{
int old=0;
int opt = set?1:0;
if( getopt (so_keepalive, &old, sizeof (old)) )
setopt (so_keepalive, &opt, sizeof (opt));
return old==0;
}
bool dontroute () const
{
int old = 0;
getopt (so_dontroute, &old, sizeof (old));
return old==0;
}
bool dontroute (bool set) const
{
int old = 0;
int opt = set?1:0;
if( getopt (so_dontroute, &old, sizeof (old)) )
setopt (so_dontroute, &opt, sizeof (opt));
return old==0;
}
bool broadcast () const
{
int old=0;
getopt (sobufroadcast, &old, sizeof (old));
return old!=0;
}
bool broadcast (bool set) const
{
int old = 0;
int opt = set?1:0;
if( getopt (sobufroadcast, &old, sizeof (old)) )
setopt (sobufroadcast, &opt, sizeof (opt));
return old!=0;
}
bool oobinline () const
{
int old=0;
getopt (so_oobinline, &old, sizeof (old));
return old==0;
}
bool oobinline (bool set) const
{
int old = 0;
int opt = set?1:0;
if( getopt (so_oobinline, &old, sizeof (old)) )
setopt (so_oobinline, &opt, sizeof (opt));
return old==0;
}
bool oob (bool b)
{
bool old = s->oob;
s->oob = b;
return old==0;
}
socklinger linger () const
{
socklinger old (0, 0);
getopt (soleninger, &old, sizeof (old));
return old;
}
socklinger linger (socklinger opt) const
{
socklinger old (0, 0);
if( getopt (soleninger, &old, sizeof (old)) )
setopt (soleninger, &opt, sizeof (opt));
return old;
}
bool atmark () const
// return true, if the read pointer for socket points to an
// out of band data
{
unsigned long arg;
if (::ioctlsocket (s->sock, SIOCATMARK, &arg) == SOCKET_ERROR)
false;
return arg!=0;
}
long nread () const
// return how many chars are available for reading in the recvbuf of
// the socket.
{
unsigned long arg;
if (::ioctlsocket (s->sock, FIONREAD, &arg) == SOCKET_ERROR)
return 0;
return (long)arg;
}
bool nbio (bool set) const
// if set is true, set socket to non-blocking io. Henceforth, any
// write or read operation will not wait if write or read would block.
// The read or write operation will result throwing a sockerr
// exception with errno set to EWOULDBLOCK.
{
unsigned long arg = set;
return ::ioctlsocket (s->sock, FIONBIO, &arg) != SOCKET_ERROR;
}
protected:
struct streamTypeDef {
int family, type, protocol;
};
streamTypeDef& getStreamType( socktype i ){
static streamTypeDef streamTypeTbl[] = {
{invalid, 0, 0 },
{AF_INET, SOCK_STREAM, IPPROTO_TCP },
{AF_INET, SOCK_DGRAM, IPPROTO_UDP },
{AF_INET, SOCK_RAW, IPPROTO_ICMP},
{AF_INET, SOCK_RAW, IPPROTO_RAW },
{AF_UNIX, SOCK_STREAM, 0 },
{AF_UNIX, SOCK_DGRAM, 0 }
};
if( i < _Myt::invalid_type || i >= sizeof(streamTypeTbl)/sizeof(streamTypeDef) )
i = _Myt::invalid_type;
return streamTypeTbl[i];
}
struct shared {
typedef shared _Myt;
typedef basic_socket myst;
SOCKET sock; // The shared socket
int state; // sock state (in,out,open, ...)
int mode; // open mode (in/out)
int stmo; // -1==block, 0==poll, >0 == waiting time in secs
int rtmo; // -1==block, 0==poll, >0 == waiting time in secs
int refcnt; // reference count
bool oob; // out of band flag
_e *ibeg, *obeg, *inext, *onext;
streamsize icnt, ocnt, isz,osz; // input and output buffer info
enum sockStates
{
inopen = ios::in,
outopen = ios::out,
open = ios::in|ios::out,
};
shared( SOCKET s, ios::openmode m, bool c = false )
: stmo(basic_socket::infinite), rtmo(basic_socket::infinite),
refcnt(1), mode(m)
{
ibeg = obeg = inext = onext = 0;
state = icnt = ocnt = isz = osz = 0;
if( (sock=s) != basic_socket::invalid && c )
{
state |= mode & _Myt::open;
if( !(state&_Myt::inopen) )
shutdown( basic_socket::shut_read ); // close not opened
if( !(state&_Myt::outopen) )
shutdown( basic_socket::shut_write ); // close not opened
}
}
~shared()
{
if( ibeg ) delete[] ibeg;
if( obeg ) delete[] obeg;
::closesocket( sock );
}
// resize buffers to size.
int_type setinputbuf( streamsize sz ){
if( sz == isz ) return isz;
if( sz == 0 || !(mode & ios::in) )
{
ibeg = new char[sz];
ibeg = inext = 0; icnt = 0; isz = 0;
return true;
}
if( sz < icnt ) sz = icnt;
if( sz < basic_socket::minbsize ) sz = basic_socket::minbsize;
if( sz > basic_socket::maxbsize ) sz = basic_socket::maxbsize;
_e *_Ti = new char[sz];
if( _Ti == NULL ) return isz;
if( ibeg )
{
if( icnt ) memcpy( _Ti + sz - icnt, inext, icnt );
delete[] ibeg;
}
inext = ibeg = _Ti; inext += sz - icnt;
return isz = sz;
}
// resize buffers to size.
int_type setoutputbuf( streamsize sz ){
if( sz == osz ) return osz;
if( sz == 0 || !(mode & ios::out) )
{
obeg = new char[sz];
obeg = onext = 0; ocnt = 0; osz = 0;
return true;
}
if( sz < onext-obeg ) sz = onext-obeg;
if( sz < basic_socket::minbsize ) sz = basic_socket::minbsize;
if( sz > basic_socket::maxbsize ) sz = basic_socket::maxbsize;
_e *_To =new char[sz];
if( _To == NULL ) return osz;
if( obeg )
{
if( onext-obeg ) memcpy( _To, obeg, onext-obeg );
delete[] obeg;
}
onext = obeg = _To; ocnt += sz - osz; onext += sz - ocnt;
return osz = sz;
}
bool shutdown( shuthow sh ){
if( sh == basic_socket::shut_read || sh == basic_socket::shutbufoth )
{
setinputbuf( 0 );
state &= ~_Myt::inopen;
mode &= ~ios::in;
}
if( sh == basic_socket::shut_write || sh == basic_socket::shutbufoth )
{
setoutputbuf( 0 );
state &= ~_Myt::outopen;
mode &= ~ios::out;
}
return ::shutdown( sock, sh ) != basic_socket::invalid;
}
bool is_readready( int ms, bool &_To )
{
int _R;
fd_set files;
FD_ZERO(&files);
FD_SET( sock, &files );
if( ms == basic_socket::infinite )
_R = ::select( sock+1, &files, 0, 0, 0 );
else
{
timeval _Tv; _Tv.tv_sec = ms/1000; _Tv.tv_usec = (ms*1000)%1000000;
_R = ::select( sock+1, &files, 0, 0, &_Tv );
}
_To = (_R == 0);
return _R && (_R != basic_socket::invalid);
}
bool is_writeready( int ms, bool &_To )
{
int _R;
fd_set files;
FD_ZERO(&files);
FD_SET( sock, &files );
if( ms == basic_socket::infinite )
_R = ::select( sock+1, 0, &files, 0, 0 );
else
{
timeval _Tv; _Tv.tv_sec = ms/1000; _Tv.tv_usec = (ms*1000)%1000000;
_R = ::select( sock+1, 0, &files, 0, &_Tv );
}
_To = (_R == 0);
return _R && (_R != basic_socket::invalid);
}
bool is_exceptionpending( int ms, bool &_To )
{
int _R;
fd_set files;
FD_ZERO(&files);
FD_SET( sock, &files );
if( ms == basic_socket::infinite )
_R = ::select( sock+1, 0, 0, &files, 0 );
else
{
timeval _Tv; _Tv.tv_sec = ms/1000; _Tv.tv_usec = (ms*1000)%1000000;
_R = ::select( sock+1, 0, 0, &files, &_Tv );
}
_To = (_R == 0);
return _R && (_R != basic_socket::invalid);
}
int_type recv( bool &_To, _e* buf, int_type len, int file = 0 )
{
int_type _R = 0;_To = false;
if( rtmo == basic_socket::infinite || is_readready( rtmo, _To ) )
{
_R = ::recv( sock, (char*)buf, len*sizeof(_e), file );
if( _R == 0 ) state &= ~_Myt::open;
else if( _R == basic_socket::invalid ) _R = 0;
}
return _R/sizeof(_e); // drop partial char received
}
int_type recv( bool &_To, sockAddr &sa, _e* buf, int_type len, int file = 0 )
{
int_type _R = 0;_To = false;
if( rtmo == basic_socket::infinite || is_readready( rtmo, _To ) )
{
int lena = sa.size();
_R = ::recvfrom( sock, (char*)buf, len*sizeof(_e), file, sa.addr(), &lena );
if( _R == 0 ) state &= ~_Myt::open;
else if( _R == basic_socket::invalid ) _R = 0;
}
return _R/sizeof(_e); // drop partial char received
}
bool recvAll( bool &_To, _e* buf, int_type len, int file = 0 )
{
int_type _R = 0;_To = false;
char *p = (char*)buf;
len *= sizeof(_e);
while( len && !_To )
{
if( rtmo == basic_socket::infinite || is_readready( rtmo, _To ) )
{
_R = ::recv( sock, p, len, file );
if( _R <= 0 ){state &= ~_Myt::open; return false; }
len -= _R; p += _R;
}
}
return !len && !_To;
}
int_type send( bool &_To, _e* buf, int_type len, int file = 0 )
{
int_type ns = 0; _To = false;
if( rtmo == basic_socket::infinite || is_writeready( rtmo, _To ) )
{
char *p = (char*)buf;
int_type n = len*sizeof(_e);
while( n )
{
int_type _R = ::send( sock, p,n*sizeof(_e), file );
if( _R == 0 ) { state &= ~_Myt::open; break; }
if( _R == basic_socket::invalid ) break;
p += _R; ns += _R; n -= _R;
}
}
return ns/sizeof(_e); // drop partial char sent
}
int_type send( bool &_To, sockAddr &sa, _e* buf, int_type len, int file = 0 )
{
int_type ns = 0; _To = false;
if( rtmo == basic_socket::infinite || is_writeready( rtmo, _To ) )
{
char *p = (char*)buf;
int_type n = len*sizeof(_e);
while( n )
{
int lena = sa.size();
int _R = ::sendto( sock, p, n, file, sa.addr(), sa.size() );
if( _R == 0 ) { state &= ~_Myt::open; break; }
if( _R == basic_socket::invalid ) break;
p += _R; ns += _R; n -= _R;
}
}
return ns/sizeof(_e); // drop partial char sent
}
int sendtimeout( int msec ){ int t = stmo; stmo = msec; return t; }
int recvtimeout( int msec ){ int t = rtmo; rtmo = msec; return t; }
};
shared * sharedSocket() const { return s; }
private:
// LOCAL VARIABLES
shared *s; // shared information
bool _tmo; // signals a time out event
};
#ifdef WIN32
#ifdef _DLL
#pragma warning(disable:4231) /* the extern before template is a non-standard extension */
extern template class cRTIMP basic_socket<char, char_traits<char> >;
extern template class cRTIMP basic_socket<wchar_t, char_traits<wchar_t> >;
#pragma warning(default:4231) /* restore previous warning */
#else
typedef basic_socket sock;
#endif // _DLL
_STD_END
#else
typedef basic_socket sock;
#endif //WIN32
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* mSC_VER */
#endif /* bufASIC_SOCKET_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -