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

📄 sockstream.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
字号:
// sockstream.C -*- C++ -*- socket library// Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>//// Permission is granted to use at your own risk and distribute this software// in source and binary forms provided the above copyright// notice and this paragraph are preserved on all copies.// This software is provided "as is" with no express or implied warranty.//// Version: 17Oct95 1.10//// You can simultaneously read and write into// a sockbuf just like you can listen and talk// through a telephone. Hence, the read and the// write buffers are different. That is, they do not// share the same memory.//// Read:// gptr() points to the start of the get area.// The unread chars are gptr() - egptr().// base() points to the read buffer//// eback() is set to base() so that pbackfail()// is called only when there is no place to// putback a char. And pbackfail() always returns EOF.//// Write:// pptr() points to the start of the put area// The unflushed chars are pbase() - pptr()// pbase() points to the write buffer.// epptr() points to the end of the write buffer.//// Output is flushed whenever one of the following conditions// holds:// (1) pptr() == epptr()// (2) EOF is written// (3) linebuffered and '\n' is written//// Unbuffered:// Input buffer size is assumed to be of size 1 and output// buffer is of size 0. That is, egptr() <= base()+1 and// epptr() == pbase().#include "SWIutilInternal.h"#include "sockstream.h"#include <string.h>#ifndef _WIN32EXTERN_C_BEGIN#include <sys/time.h>#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <sys/ioctl.h>#ifdef _solaris_#include <sys/filio.h>#endifEXTERN_C_END#else#include <winsock.h>#ifdef EINTR#undef EINTR#endif#define EINTR WSAEINTR#endif /* !_WIN32 */#ifndef BUFSIZ#  define BUFSIZ 1024#endif#ifdef FD_ZERO#  undef FD_ZERO    // bzero causes so much trouble to us#endif#define FD_ZERO(p) (memset ((p), 0, sizeof *(p)))#define LOG_ERROR(_err, _func) Error(_err, L"%s%s", L"Func", _func);#ifdef _WIN32#define LOG_ERROR_DETAILED(_err, _func) \{ \  int wserr = WSAGetLastError(); \  Error(_err, L"%s%s%s%i", L"Func", _func, L"WinsockError", wserr); \}#else#define LOG_ERROR_DETAILED(_err, _func) LOG_ERROR(_err, _func)#endifsockbuf::sockbuf (const VXIchar *moduleName, VXIlogInterface *pVXILog, 		  VXIunsigned diagTagBase, SOCKET soc)  : streambuf(), SWIutilLogger(moduleName, pVXILog, diagTagBase),    rep (new sockcnt (soc, 1)), stmo (-1), rtmo (-1){  xflags (0);  xsetflags (_S_LINE_BUF);}sockbuf::sockbuf (const VXIchar *moduleName, VXIlogInterface *pVXILog, 		  VXIunsigned diagTagBase, int domain, sockbuf::type st,		  int proto)  : streambuf(), SWIutilLogger(moduleName, pVXILog, diagTagBase),    rep (0), stmo (-1), rtmo (-1){  SOCKET soc = ::socket (domain, st, proto);  rep = new sockcnt (soc, 1);  xflags (0);  if ((! rep) || (rep->sock == INVALID_SOCKET))     error ("invalid socket");  xsetflags (_S_LINE_BUF);}sockbuf::sockbuf (const sockbuf& sb)  : streambuf(), SWIutilLogger(sb),    rep (sb.rep), stmo (sb.stmo), rtmo (sb.rtmo){  xflags (0);  rep->cnt++;  xsetflags (_S_LINE_BUF);}sockbuf& sockbuf::operator = (const sockbuf& sb){  if (this != &sb && rep != sb.rep && rep->sock != sb.rep->sock) {    this->sockbuf::~sockbuf();    rep  = sb.rep; stmo = sb.stmo; rtmo = sb.rtmo;     SWIutilLogger::Create(sb.GetModuleName(), sb.GetLog(), sb.GetDiagBase());    rep->cnt++;#ifdef _S_NOLIBGXX    xflags (sb.xflags ());#else    // xflags () is a non-const member function in libg++.    xflags (((sockbuf&)sb).xflags ());#endif  }  return *this;}sockbuf::~sockbuf (){  overflow (EOF);  if (rep->cnt == 1 && !(xflags () & _S_DELETE_DONT_CLOSE)) close ();  delete [] base ();  if (--rep->cnt == 0) delete rep;}sockbuf* sockbuf::open (type, int){  return 0;}sockbuf* sockbuf::close(){#ifdef _WIN32  if (rep->sock != INVALID_SOCKET)  {     closesocket(rep->sock);     rep->sock = INVALID_SOCKET;  }#else  if (rep->sock >= 0)  {    if (::close (rep->sock) == -1) return this;    rep->sock = -1;  }#endif  return 0;}_G_ssize_t sockbuf::sys_read (char* buf, _G_ssize_t len)// return EOF on eof, 0 on timeout, and # of chars read on success{  return read (buf, len);}_G_ssize_t sockbuf::sys_write (const void* buf, long len)// return written_length; < len indicates error{  return write (buf, (int) len);}int sockbuf::flush_output()// return 0 when there is nothing to flush or when the flush is a success// return EOF when it could not flush{  if (pptr () <= pbase ()) return 0;  if (!(xflags () & _S_NO_WRITES)) {    int wlen   = pptr () - pbase ();    int wval   = sys_write (pbase (), wlen);    int status = (wval == wlen)? 0: EOF;#ifndef _WIN32    if (unbuffered()) setp (pbase (), pbase ());    else#endif		setp (pbase (), pbase () + BUFSIZ);    return status;  }  return EOF;}int sockbuf::sync (){  return flush_output ();}int sockbuf::doallocate ()// return 1 on allocation and 0 if there is no need{  if (!base ()) {    char*	buf = new char[2*BUFSIZ];    setb (buf, buf+BUFSIZ);    setg (buf, buf, buf);    buf += BUFSIZ;    setp (buf, buf+BUFSIZ);    return 1;  }  return 0;}underflow_ret_t sockbuf::underflow (){  if (xflags () & _S_NO_READS) return EOF;  if (gptr () < egptr ()) return *(unsigned char*)gptr ();  if (base () == 0 && doallocate () == 0) return EOF;  int bufsz = unbuffered () ? 1: BUFSIZ;  int rval = sys_read (base (), bufsz);  if (rval == EOF) {    xsetflags (_S_EOF_SEEN);    return EOF;  }else if (rval == 0)    return EOF;  setg (eback (), base (), base () + rval);  return *(unsigned char*)gptr ();}sockbuf::int_type sockbuf::overflow (sockbuf::int_type c)// if c == EOF, return flush_output();// if c == '\n' and linebuffered, insert c and// return (flush_output()==EOF)? EOF: c;// otherwise insert c into the buffer and return c{  if (c == EOF) return flush_output ();  if (xflags () & _S_NO_WRITES) return EOF;  if (pbase () == 0 && doallocate () == 0) return EOF;  if (pptr () >= epptr() && flush_output () == EOF)    return EOF;  xput_char (c);  if ((unbuffered () || linebuffered () && c == '\n' || pptr () >= epptr ())      && flush_output () == EOF)    return EOF;  return c;}int sockbuf::xsputn (const char* s, int n){  if (n <= 0) return 0;  const unsigned char* p = (const unsigned char*)s;  for (int i=0; i<n; i++, p++) {    if (*p == '\n') {      if (overflow (*p) == EOF) return i;    } else      if (sputc (*p) == EOF) return i;  }  return n;}int sockbuf::bind (sockAddr& sa){  return ::bind (rep->sock, sa.addr (), sa.size ());}int sockbuf::connect (sockAddr& sa){  if (::connect(rep->sock, sa.addr (), sa.size()) != 0) {#ifdef _WIN32    int wserr = WSAGetLastError();    if (wserr != WSAEWOULDBLOCK) {      Error(500, L"%s%s%s%i", L"Func", L"connect", L"WinsockError", wserr);      return -1;    }#else    if (errno != EINPROGRESS) {      Error(500, L"%s%s%s%i", L"Func", L"connect", L"errno", errno);      return -1;    }#endif  }  return 0;}int sockbuf::listen (int num){  return ::listen (rep->sock, num);}sockbuf	sockbuf::accept (sockAddr& sa){  socklen_t len = sa.size ();  SOCKET soc = INVALID_SOCKET;  while ((soc = ::accept (rep->sock, sa.addr (), &len)) == INVALID_SOCKET	 && errno == EINTR);  return sockbuf(GetModuleName(), GetLog(), GetDiagBase(), soc);}sockbuf	sockbuf::accept (){  SOCKET soc = INVALID_SOCKET;  while ((soc = ::accept (rep->sock, 0, 0)) == INVALID_SOCKET	 && errno == EINTR);  return sockbuf(GetModuleName(), GetLog(), GetDiagBase(), soc);}int sockbuf::read (void* buf, int len){#ifdef _WIN32  return recv (buf, len); // Winsock uses recv#else  if (rtmo != -1 && is_readready (rtmo)==0) return 0;  int	rval;  if ((rval = ::read (rep->sock, (char*) buf, len)) == -1)    error("read");  return (rval==0) ? EOF: rval;#endif // _WIN32}int sockbuf::recv (void* buf, int len, int msgf){  if (rtmo != -1 && is_readready (rtmo)==0) return 0;  int	rval;  if ((rval = ::recv (rep->sock, (char*) buf, len, msgf)) == -1)    LOG_ERROR_DETAILED (500, L"recv");  return (rval==0) ? EOF: rval;}int sockbuf::recvfrom (sockAddr& sa, void* buf, int len, int msgf){  if (rtmo != -1 && is_readready (rtmo)==0) return 0;  int rval;  socklen_t sa_len = sa.size ();  if ((rval = ::recvfrom (rep->sock, (char*) buf, len,			  msgf, sa.addr (), &sa_len)) == -1)    LOG_ERROR_DETAILED (500, L"recvfrom");  return (rval==0) ? EOF: rval;}int sockbuf::write(const void* buf, int len){#ifdef _WIN32  return send(buf, len); // Winsock uses send#else  if (stmo != -1 && is_writeready (stmo)==0) return 0;  int	wlen=0;  while(len>0) {    int	wval;    if ((wval = ::write (rep->sock, (char*) buf, len)) == -1) {      error ("sockbuf::write");      return wval;    }    len -= wval;    wlen += wval;  }  return wlen; // == len if every thing is all right#endif // _WIN32}int sockbuf::send (const void* buf, int len, int msgf){  if (stmo != -1 && is_writeready (stmo)==0) return 0;  int	wlen=0;  while(len>0) {    int	wval;    if ((wval = ::send (rep->sock, (char*) buf, len, msgf)) == -1) {      LOG_ERROR_DETAILED (500, L"send");      return wval;    }    len -= wval;    wlen += wval;  }  return wlen;}int sockbuf::sendto (sockAddr& sa, const void* buf, int len, int msgf){  if (stmo != -1 && is_writeready (stmo)==0) return 0;  int	wlen=0;  while(len>0) {    int	wval;    if ((wval = ::sendto (rep->sock, (char*) buf, len,			  msgf, sa.addr (), sa.size())) == -1) {      LOG_ERROR_DETAILED (500, L"sendto");      return wval;    }    len -= wval;    wlen += wval;  }  return wlen;}#if !defined (__linux__) && !defined(_WIN32)// linux does not have sendmsg or recvmsgint sockbuf::recvmsg (msghdr* msg, int msgf){  if (rtmo != -1 && is_readready (rtmo)==0) return 0;  int	rval;  if ((rval = ::recvmsg(rep->sock, msg, msgf)) == -1)    error ("sockbuf::recvmsg");  return (rval==0)? EOF: rval;}int sockbuf::sendmsg (msghdr* msg, int msgf){  if (stmo != -1 && is_writeready (stmo)==0) return 0;  int	wval;  if ((wval = ::sendmsg (rep->sock, msg, msgf)) == -1)    error("sendmsg");  return wval;}#endif //!__linux__int sockbuf::sendtimeout (int wp){  int oldstmo = stmo;  stmo = (wp < 0) ? -1: wp;  return oldstmo;}int sockbuf::recvtimeout (int wp){  int oldrtmo = rtmo;  rtmo = (wp < 0) ? -1: wp;  return oldrtmo;}int sockbuf::is_readready (int wp_sec, int wp_usec) const{  fd_set rfds;  FD_ZERO (&rfds);  FD_SET (rep->sock, &rfds);  fd_set efds;  FD_ZERO (&efds);  FD_SET (rep->sock, &efds);  timeval tv;  tv.tv_sec  = wp_sec;  tv.tv_usec = wp_usec;  int ret = select (rep->sock+1, &rfds, 0, &efds, (wp_sec == -1) ? 0: &tv);  if (ret < 0)   {    LOG_ERROR_DETAILED (500, L"select");    return ret;  }  else if (ret == 0)  {    LOG_ERROR (501, L"select");    return ret;  }  if (FD_ISSET(rep->sock, &efds))  {    LOG_ERROR (502, L"select");    return -1;  }  return FD_ISSET(rep->sock,&rfds);}int sockbuf::is_writeready (int wp_sec, int wp_usec) const{  fd_set wfds;  FD_ZERO (&wfds);  FD_SET (rep->sock, &wfds);  fd_set efds;  FD_ZERO (&efds);  FD_SET (rep->sock, &efds);  timeval tv;  tv.tv_sec  = wp_sec;  tv.tv_usec = wp_usec;  int ret = select (rep->sock+1, 0, &wfds, &efds, (wp_sec == -1) ? 0: &tv);  if (ret < 0)   {    LOG_ERROR_DETAILED (500, L"select");    return ret;  }  else if (ret == 0)  {    LOG_ERROR (501, L"select");    return ret;  }  if (FD_ISSET(rep->sock, &efds))  {    LOG_ERROR (502, L"select");    return -1;  }  return FD_ISSET(rep->sock,&wfds);}int sockbuf::is_exceptionpending (int wp_sec, int wp_usec) const{  fd_set fds;  FD_ZERO (&fds);  FD_SET  (rep->sock, &fds);  timeval tv;  tv.tv_sec = wp_sec;  tv.tv_usec = wp_usec;  int ret = select (rep->sock+1, 0, 0, &fds, (wp_sec == -1) ? 0: &tv);  if (ret == -1) {    LOG_ERROR_DETAILED (500, L"select");    return 0;  }  return ret;}void sockbuf::shutdown (shuthow sh){  switch (sh) {  case shut_read:    xsetflags(_S_NO_READS);    break;  case shut_write:    xsetflags(_S_NO_WRITES);    break;  case shut_readwrite:    xsetflags(_S_NO_READS|_S_NO_WRITES);    break;  }  if (::shutdown(rep->sock, sh) == INVALID_SOCKET)    error("shutdown");}int sockbuf::getopt (option op, void* buf, int len, level l) const{  socklen_t rlen = len;  if (::getsockopt (rep->sock, l, op, (char*) buf, &rlen) == -1)    error ("sockbuf::getopt");  return rlen;}int sockbuf::setBlocking(bool blocking){  unsigned long x = (unsigned long) !blocking;#ifdef _WIN32  return ioctlsocket(rep->sock, FIONBIO, &x);#else  return ioctl(rep->sock, FIONBIO, &x);#endif}void sockbuf::setopt (option op, void* buf, int len, level l) const{  if (::setsockopt (rep->sock, l, op, (char*) buf, len) == -1)    error ("sockbuf::setopt");}sockbuf::type sockbuf::gettype () const{  int	ty=0;  getopt (so_type, &ty, sizeof (ty));  return sockbuf::type(ty);}int sockbuf::clearerror () const{  int 	err=0;  getopt (so_error, &err, sizeof (err));  return err;}int sockbuf::debug (int opt) const{  int old=0;  getopt (so_debug, &old, sizeof (old));  if (opt != -1)    setopt (so_debug, &opt, sizeof (opt));  return old;}int sockbuf::reuseaddr (int opt) const{  int old=0;  getopt (so_reuseaddr, &old, sizeof (old));  if (opt != -1)    setopt (so_reuseaddr, &opt, sizeof (opt));  return old;}int sockbuf::keepalive (int opt) const{  int old=0;  getopt (so_keepalive, &old, sizeof (old));  if (opt != -1)    setopt (so_keepalive, &opt, sizeof (opt));  return old;}int sockbuf::dontroute (int opt) const{  int old=0;  getopt (so_dontroute, &old, sizeof (old));  if (opt != -1)    setopt (so_dontroute, &opt, sizeof (opt));  return old;}int sockbuf::broadcast (int opt) const{  int old=0;  getopt (so_broadcast, &old, sizeof (old));  if (opt != -1)    setopt (so_broadcast, &opt, sizeof (opt));  return old;}int sockbuf::oobinline (int opt) const{  int old=0;  getopt (so_oobinline, &old, sizeof (old));  if (opt != -1)    setopt (so_oobinline, &opt, sizeof (opt));  return old;}int sockbuf::linger (int opt) const{  socklinger	old (0, 0);  getopt (so_linger, &old, sizeof (old));  if (opt > 0) {    socklinger nw (1, opt);    setopt (so_linger, &nw, sizeof (nw));  }else if (opt == 0) {    socklinger nw (0, old.l_linger);    setopt (so_linger, &nw, sizeof (nw));  }  return old.l_onoff ? old.l_linger: -1;}int sockbuf::sendbufsz (int  sz) const{  int old=0;  getopt (so_sndbuf, &old, sizeof (old));  if (sz >= 0)    setopt (so_sndbuf, &sz, sizeof (sz));  return old;}int sockbuf::recvbufsz (int sz) const{  int old=0;  getopt (so_rcvbuf, &old, sizeof (old));  if (sz >= 0)    setopt (so_rcvbuf, &sz, sizeof (sz));  return old;}void sockbuf::error (const char* msg) const{  SOCK_ERROR("sockbuf", msg);}isockstream::~isockstream (){}osockstream::~osockstream (){}iosockstream::~iosockstream (){}

⌨️ 快捷键说明

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