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

📄 swisocket.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/****************License************************************************
 * Vocalocity OpenVXI
 * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
 * registered trademarks of Vocalocity, Inc. 
 * OpenVXI is a trademark of Scansoft, Inc. and used under license 
 * by Vocalocity.
 ***********************************************************************/

#if _MSC_VER >= 1100    // Visual C++ 5.x
#pragma warning( disable : 4786 4503 )
#endif

#ifdef _WIN32
#include <winsock2.h>
#define WSA_LAST_ERROR WSAGetLastError()
#define WSA_ERROR_NAME L"WinsockError"
#else
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#ifdef _solaris_
#include <stropts.h>
#include <fcntl.h>
#include <string.h>
#endif
#define WSA_LAST_ERROR errno
#define WSA_ERROR_NAME L"errno"
#define WSAEADDRINUSE EADDRINUSE
#define WSAECONNABORTED ECONNABORTED
#define WSAECONNRESET ECONNRESET
#define WSAECONNREFUSED ECONNREFUSED
#define WSAEHOSTDOWN EHOSTDOWN
#define WSAEHOSTUNREACH EHOSTUNREACH
#define WSAEWOULDBLOCK EINPROGRESS
#define WSAEACCESS EACCESS
#define WSAENOTSOCK EBADF
#define WSAEINTR EINTR
#define closesocket close
#define ioctlsocket ioctl
#endif
#include "SWIsocket.hpp"
#include "SWIipAddress.hpp"


static timeval* millisecToTimeval(long millisec, timeval& tv)
{
  if (millisec < 0)
  {
    tv.tv_sec  = -1;
    tv.tv_usec = -1;
    return NULL;
  }

  tv.tv_sec = (millisec / 1000);
  tv.tv_usec = (millisec % 1000) * 1000;
  return &tv;
}




SWIsocket::SWIsocket(Type socktype,
                     SWIutilLogger *logger):
  _logger(logger), _sd(INVALID_SOCKET),
  _bound(false), _connected(false), _shutIn(false), _shutOut(false),
  _remoteAddress(NULL), _localAddress(NULL), _rtmo(-1), _stmo(-1),
  _inStream(NULL), _outStream(NULL)
{
  _sd = socket(AF_INET, socktype, 0);
  if (_sd == INVALID_SOCKET)
  {
    error(L"socket", 500, WSA_LAST_ERROR);
  }
}

SWIsocket::SWIsocket(const SWIsocket *socket, SOCKET sd):
  _logger(socket->_logger), _sd(sd), _bound(true), _connected(true),
  _shutIn(false), _shutOut(false),
  _remoteAddress(NULL), _localAddress(NULL),
  _rtmo(socket->_rtmo), _stmo(socket->_stmo),
  _inStream(NULL), _outStream(NULL)
{}

SWIsocket::~SWIsocket()
{
  close();
  if (_inStream != NULL)
  {
    _inStream->_sock = NULL;
  }

  if (_outStream != NULL)
  {
    _outStream->_sock = NULL;
  }
  delete _remoteAddress;
  delete _localAddress;
}

SWIstream::Result SWIsocket::connect(const SWIipAddress& endpoint, long timeout)
{
  SWIstream::Result rc = SWIstream::SUCCESS;

  unsigned long nonblocking = 1;
  int flags = 0;
  timeval tv;

  timeval *ptv = millisecToTimeval(timeout, tv);

  if (ptv != NULL)
  {
#ifdef _solaris_
		flags = fcntl(_sd, F_GETFL, 0);
		flags  |= O_NONBLOCK;
		fcntl(_sd, F_SETFL, flags);
#else
    ioctlsocket(_sd, FIONBIO, &nonblocking);
    nonblocking = 0;
#endif
  }

  if (::connect(_sd, endpoint.addr(), endpoint.size()) != 0)
  {
    int wserr = WSA_LAST_ERROR;
    if (wserr != WSAEWOULDBLOCK)
    {
      error(L"connect", 500, wserr);
      rc = SWIstream::FAILURE;
      goto cleanup;
    }
  }

  if (ptv != NULL)
  {
    int status = is_writeready(ptv);
    if (status == 0)
    {
      rc = SWIstream::TIMED_OUT;
      goto cleanup;
    }
    if (status < 0)
    {
      rc = SWIstream::OPEN_ERROR;
      goto cleanup;
    }
  }

  _bound = _connected = true;
 cleanup:

  // restore blocking mode.
  if (ptv != NULL)
  {
#ifdef _solaris_
		flags = fcntl(_sd, F_GETFL, 0);
		flags &= ~O_NONBLOCK;
		fcntl(_sd, F_SETFL, flags);
#else
    ioctlsocket(_sd, FIONBIO, &nonblocking);
#endif
  }
  return rc;
}

SWIstream::Result SWIsocket::connect(const char *hostname, int port, long timeout)
{
  SWIipAddress endpoint(hostname, port, _logger);

  return connect(endpoint, timeout);
}


SWIstream::Result SWIsocket::connect(unsigned long addr, int port, long timeout)
{
  SWIipAddress endpoint(addr, port, _logger);
  return connect(endpoint, timeout);
}

SWIstream::Result SWIsocket::connect(unsigned long addr,
                                     const char *service_name,
                                     const char *protocol_name,
                                     long timeout)
{
  SWIipAddress endpoint(addr, service_name, protocol_name, _logger);
  return connect(endpoint, timeout);
}

SWIstream::Result SWIsocket::connect(const char *host,
                                     const char *service_name,
                                     const char *protocol_name,
                                     long timeout)
{
  SWIipAddress endpoint(host, service_name, protocol_name, _logger);
  return connect(endpoint, timeout);
}

SWIstream::Result SWIsocket::bind(const SWIipAddress& sa)
{
  int rc = ::bind(_sd, sa.addr (), sa.size ());
  if (rc != 0)
  {
    error(L"bind", 500, WSA_LAST_ERROR);
    return SWIstream::FAILURE;
  }
  _bound = true;
  return SWIstream::SUCCESS;
}

SWIstream::Result SWIsocket::bind()
{
  SWIipAddress sa(_logger);
  return bind(sa);
}

SWIstream::Result SWIsocket::bind(unsigned long addr, int port_no)
{
  SWIipAddress sa(addr, port_no, _logger);
  return bind(sa);
}

SWIstream::Result SWIsocket::bind(const char* host_name, int port_no)
{
  SWIipAddress sa(host_name, port_no, _logger);
  return bind (sa);
}

SWIstream::Result SWIsocket::bind(unsigned long addr,
                                  const char* service_name,
                                  const char* protocol_name)
{
  SWIipAddress sa(addr, service_name, protocol_name, _logger);
  return bind(sa);
}

SWIstream::Result SWIsocket::bind(const char* host_name,
                                  const char* service_name,
                                  const char* protocol_name)
{
  SWIipAddress sa(host_name, service_name, protocol_name, _logger);
  return bind(sa);
}


SWIstream::Result SWIsocket::listen(int backlog)
{
  int rc = ::listen (_sd, backlog);
  if (rc != 0)
  {
    error(L"listen", 500, WSA_LAST_ERROR);
    return SWIstream::FAILURE;
  }
  return SWIstream::SUCCESS;
}

SWIsocket *SWIsocket::accept(SWIipAddress& sa)
{
  int wserr;
  socklen_t len = sa.size();
  SOCKET soc = INVALID_SOCKET;
  while ((soc = ::accept (_sd, sa.addr(), &len)) == INVALID_SOCKET
	 && (wserr = WSA_LAST_ERROR) == WSAEINTR);
  if (soc == INVALID_SOCKET)
  {
    error(L"accept", 500, wserr);
    return NULL;
  }
  return new SWIsocket(this, soc);
}

SWIsocket* SWIsocket::accept()
{
  int wserr;
  SOCKET soc = INVALID_SOCKET;
  while ((soc = ::accept (_sd, NULL, NULL)) == INVALID_SOCKET
	 && (wserr = WSA_LAST_ERROR) == WSAEINTR);
  if (soc == INVALID_SOCKET)
  {
    error(L"accept", 500, wserr);
    return NULL;
  }
  return new SWIsocket(this, soc);
}


const SWIipAddress *SWIsocket::getRemoteAddress() const
{
  //   if (!_connected)
  //     return NULL;

  if (_remoteAddress != NULL)
    return _remoteAddress;

  _remoteAddress = new SWIipAddress(_logger);

  socklen_t len = _remoteAddress->size();

  if (::getpeername(_sd, _remoteAddress->addr(), &len) != 0)
  {
    error(L"getpeername", 500, WSA_LAST_ERROR);
    delete _remoteAddress;
    _remoteAddress = NULL;
  }
  return _remoteAddress;
}

const SWIipAddress *SWIsocket::getLocalAddress() const
{
  //if (!_bound)
  //return NULL;

  if (_localAddress != NULL)
    return _localAddress;

  _localAddress = new SWIipAddress(_logger);

  socklen_t len = _localAddress->size();

  if (::getsockname(_sd, _localAddress->addr(), &len) != 0)
  {
    error(L"getsockname", 500, WSA_LAST_ERROR);
    delete _localAddress;
    _localAddress = NULL;
  }

  return _localAddress;
}


int SWIsocket::getRemotePort() const
{
  const SWIipAddress* addr = getRemoteAddress();
  if (addr == NULL)
  {
    return 0;
  }
  else
    return addr->getport();
}

int SWIsocket::getLocalPort() const
{
  const SWIipAddress* addr = getLocalAddress();
  if (addr == NULL)
  {
    return 0;
  }
  else
    return addr->getport();
}

SWIstream::Result SWIsocket::close()
{
  if (_sd != INVALID_SOCKET)
  {
    ::closesocket(_sd);
    _sd = INVALID_SOCKET;
  }
  return SWIstream::SUCCESS;
}


SWIinputStream *SWIsocket::getInputStream()
{
  if (_inStream == NULL)
  {
    _inStream = new InputStream(this);
  }
  return _inStream;
}

SWIoutputStream *SWIsocket::getOutputStream()
{
  if (_outStream == NULL)
  {
    _outStream = new OutputStream(this);
  }

  return _outStream;
}

SWIsocket::InputStream::InputStream(SWIsocket *sock):
  _sock(sock)
{}

SWIsocket::InputStream::~InputStream()
{
  if (_sock != NULL)
  {
    _sock->shutdown(shut_read);
    _sock->_inStream = NULL;
  }
}

int SWIsocket::InputStream::readBytes(void *data, int dataSize)
{
  return _sock != NULL ? _sock->recv(data, dataSize) : SWIstream::ILLEGAL_STATE;
}

SWIstream::Result SWIsocket::InputStream::close()
{
  if (_sock == NULL)
    return SWIstream::ILLEGAL_STATE;

  return _sock->shutdown(shut_read);
}

SWIstream::Result SWIsocket::InputStream::waitReady(long timeoutMs)
{
  if (_sock == NULL)
    return SWIstream::ILLEGAL_STATE;

  switch (_sock->is_readready(timeoutMs))
  {
   case 1:
     return SUCCESS;
   case 0:
     return TIMED_OUT;
   default:
     return FAILURE;
  }
}

SWIsocket::OutputStream::OutputStream(SWIsocket *sock):
  _sock(sock)
{}

SWIsocket::OutputStream::~OutputStream()
{
  if (_sock != NULL)
  {
    _sock->shutdown(shut_write);
    _sock->_outStream = NULL;
  }
}

int SWIsocket::OutputStream::writeBytes(const void *buffer, int bufferSize)
{
  return _sock != NULL ? _sock->send(buffer, bufferSize) : SWIstream::ILLEGAL_STATE;
}

⌨️ 快捷键说明

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