📄 swisocket.cpp
字号:
/****************License************************************************ * * Copyright 2000-2003. ScanSoft, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.2 which is * included with this software. * * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech, * SpeechWorks and the SpeechWorks logo are registered trademarks or * trademarks of SpeechWorks International, Inc. in the United States * and other countries. * ***********************************************************************/ #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 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 + -