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

📄 unixsocket.cpp

📁 "More for C++" is a class library that provides some features that are usually common for object ori
💻 CPP
字号:
////  This file is part of the "More for C++" library////  Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)////  The "More for C++" library is free software; you can redistribute it and/or//  modify it under the terms of the license that comes with this package.////  Read "license.txt" for more details.////  THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED//  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES//  OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <malloc.h>#include <netdb.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <more/create.hpp>#include "unixsocket.hpp"using namespace more;using namespace more::io;using namespace more::os;using namespace more::os::unix_;////////////////////////////////////////////////////////////////////////////////UnixSocketAddress::UnixSocketAddress(  struct sockaddr_in& rSockAddrIn): m_rSockAddrIn( rSockAddrIn ){}////////////////////////////////////////////////////////////////////////////////void UnixSocketAddress::resolve(  const String& sNameOfHost,  int           nNoOfPort) throw( IOException ){  m_rSockAddrIn.sin_family = PF_INET;  m_rSockAddrIn.sin_addr.s_addr = inet_addr( sNameOfHost );  m_rSockAddrIn.sin_port = htons( ( u_short ) nNoOfPort );  if( m_rSockAddrIn.sin_addr.s_addr == INADDR_NONE )  {    struct hostent* pHost = gethostbyname( sNameOfHost );    if( pHost == 0 )    {      throw IOException( -1, "Could not resolve name of host" );    }    memcpy( &m_rSockAddrIn.sin_addr, pHost -> h_addr, pHost -> h_length );  }}////////////////////////////////////////////////////////////////////////////////UnixAcceptorSocket::UnixAcceptorSocket( ){  m_socket = socket( PF_INET, SOCK_STREAM, 0 );  m_nNoOfPort = -1;  m_bHasBeenCancelled = false;}////////////////////////////////////////////////////////////////////////////////bool UnixAcceptorSocket::isValid( ) const{  return m_socket != -1;}////////////////////////////////////////////////////////////////////////////////void UnixAcceptorSocket::bind(  const String& sNameOfHost,  size_t        nNoOfPort) throw( IOException ){  throwIfNotValid( );  int nResult = 0;  memset( &m_sockAddrIn, 0, sizeof( sockaddr_in ) );  if( sNameOfHost.getLength( ) == 0 )  {    m_sockAddrIn.sin_family = PF_INET;    m_sockAddrIn.sin_addr.s_addr = INADDR_ANY;    m_sockAddrIn.sin_port = htons( ( u_short ) nNoOfPort );  }  else  {    UnixSocketAddress address( m_sockAddrIn );    address.resolve( sNameOfHost, nNoOfPort );  }  nResult = ::bind( m_socket, ( const sockaddr* ) &m_sockAddrIn, sizeof( sockaddr_in ) );  if( nResult == 0 )  {    socklen_t nSizeOfAddr = sizeof( sockaddr_in );    nResult = ::getsockname( m_socket, ( sockaddr* ) &m_sockAddrIn, &nSizeOfAddr );    if( nResult == 0 )    {      m_nNoOfPort = ntohs( m_sockAddrIn.sin_port );    }  }  if( nResult != 0 )  {    close( );    throw IOException( -1, "Unable to bind socket" );  }}////////////////////////////////////////////////////////////////////////////////void UnixAcceptorSocket::bind(  size_t nNoOfPort) throw( IOException ){  bind( "", nNoOfPort );}////////////////////////////////////////////////////////////////////////////////String UnixAcceptorSocket::getNameOfHost( ) const{  char sNameOfHost[512];  gethostname( sNameOfHost, 511 );  return sNameOfHost;}////////////////////////////////////////////////////////////////////////////////size_t UnixAcceptorSocket::getNoOfPort( ) const{  return m_nNoOfPort;}////////////////////////////////////////////////////////////////////////////////p<Socket> UnixAcceptorSocket::accept( ) throw( IOException ){  throwIfNotValid( );  p<Socket>           pResult;  int                 nResultOfListen = -1;  int                 socket = -1;  struct sockaddr_in  sockAddrIn;  socklen_t           sizeOfSockAddrIn = sizeof( sockaddr_in );  nResultOfListen = ::listen( m_socket, 1 );  if( nResultOfListen < 0 )  {    throw IOException( -1, "Error while listening to socket" );  }  socket = ::accept( m_socket, ( sockaddr* ) &sockAddrIn, &sizeOfSockAddrIn );  if( !m_bHasBeenCancelled )  {    if( socket == -1 )    {      throw IOException( -1, "Error while accepting socket" );    }    pResult = CREATE UnixSocket( socket, sockAddrIn );  }  return pResult;}////////////////////////////////////////////////////////////////////////////////void UnixAcceptorSocket::cancel( ) throw( IOException ){  throwIfNotValid( );  m_bHasBeenCancelled = true;  ::close( m_socket );  m_socket = -1;}////////////////////////////////////////////////////////////////////////////////void UnixAcceptorSocket::close( ) throw( IOException ){  if( m_bHasBeenCancelled )  {    m_bHasBeenCancelled = false;  }  else  {    throwIfNotValid( );    ::close( m_socket );    m_socket = -1;  }}////////////////////////////////////////////////////////////////////////////////void UnixAcceptorSocket::finalize( ){  if( isValid( ) )  {    close( );  }}////////////////////////////////////////////////////////////////////////////////UnixSocket::UnixSocket( ){  m_socket = socket( PF_INET, SOCK_STREAM, 0 );  m_bHasBeenConnected = false;}////////////////////////////////////////////////////////////////////////////////UnixSocket::UnixSocket(  int           socket,  sockaddr_in&  rSockAddrIn): m_socket( socket ), m_sockAddrIn( rSockAddrIn ){  m_bHasBeenConnected = true;}////////////////////////////////////////////////////////////////////////////////bool UnixSocket::isValid( ) const{  return m_socket != -1;}////////////////////////////////////////////////////////////////////////////////void UnixSocket::connect(  const String& sNameOfHost,  size_t        nNoOfPort) throw( IOException ){  throwIfNotValid( );  UnixSocketAddress address( m_sockAddrIn );  int               nResultOfConnect = -1;  if( m_bHasBeenConnected )  {    throw IOException( -1, "Socket has already been connected" );  }  address.resolve( sNameOfHost, nNoOfPort );  nResultOfConnect = ::connect( m_socket, ( const sockaddr* ) &m_sockAddrIn, sizeof( sockaddr_in ) );  if( nResultOfConnect < 0 )  {    throw IOException( -1, "Unable to connect to socket" );  }  m_bHasBeenConnected = true;}////////////////////////////////////////////////////////////////////////////////String UnixSocket::getNameOfHost( ) const{  int         nErrorCode;  sockaddr_in address;  socklen_t   nSizeOfBuffer = sizeof( address );  nErrorCode = getpeername( m_socket, ( struct sockaddr* ) &address, &nSizeOfBuffer );  if( nErrorCode != 0 )  {    throw IOException( nErrorCode, "UnixSocket::getNameOfHost failed" );  }  return inet_ntoa( address.sin_addr );}////////////////////////////////////////////////////////////////////////////////size_t UnixSocket::getNoOfPort( ) const{  return m_sockAddrIn.sin_port;}////////////////////////////////////////////////////////////////////////////////p<InputStream> UnixSocket::getInputStream( ) throw( IOException ){  throwIfNotConnected( );  return CREATE UnixSocketInputStream( this );}////////////////////////////////////////////////////////////////////////////////p<OutputStream> UnixSocket::getOutputStream( ) throw( IOException ){  throwIfNotConnected( );  return CREATE UnixSocketOutputStream( this );}////////////////////////////////////////////////////////////////////////////////void UnixSocket::close( ) throw( IOException ){  throwIfNotValid( );  m_bHasBeenConnected = false;  ::close( m_socket );  m_socket = -1;}////////////////////////////////////////////////////////////////////////////////void UnixSocket::finalize( ){  if( isValid( ) )  {    close( );  }}////////////////////////////////////////////////////////////////////////////////size_t UnixSocket::available( ) throw( IOException ){  throwIfNotConnected( );  return 0;}////////////////////////////////////////////////////////////////////////////////bool UnixSocket::hasBeenClosed( ) throw( IOException ){  throwIfNotConnected( );  return m_socket == -1;}////////////////////////////////////////////////////////////////////////////////size_t UnixSocket::skip(  size_t bytesToSkip) throw( IOException ){  size_t  bytesLeftToSkip = bytesToSkip;  void*   pBuffer = malloc( 4096 );  while( bytesLeftToSkip > 4096 )  {    read( pBuffer, 4096 );    bytesLeftToSkip -= 4096;  }  if( bytesLeftToSkip > 0 )  {    read( pBuffer, bytesLeftToSkip );  }  free( pBuffer );  return bytesToSkip;}////////////////////////////////////////////////////////////////////////////////size_t UnixSocket::read(  void*   pBuffer,  size_t  nMaxNoOfBytes) throw( IOException ){  throwIfNotValid( );  throwIfNotConnected( );  int nNoOfReceivedBytes = recv( m_socket, ( char* ) pBuffer, nMaxNoOfBytes, 0 );  if( nNoOfReceivedBytes < 0 )  {    throw IOException( -1, "Error while reading from socket" );  }  return ( size_t ) nNoOfReceivedBytes;}////////////////////////////////////////////////////////////////////////////////void UnixSocket::write(  const void* pBuffer,  size_t      nNoOfBytes) throw( IOException ){  throwIfNotValid( );  throwIfNotConnected( );  int nNoOfSentBytes = ::send( m_socket, ( const char* ) pBuffer, nNoOfBytes, 0 );  if( nNoOfSentBytes <= 0 )  {    throw IOException( -1, "Error while writing to socket" );  }}////////////////////////////////////////////////////////////////////////////////size_t UnixSocket::rewind(  size_t nNoOfBytes) throw( IOException ){  throw IOException( 0, "Rewind on this output-stream not supported" );  return 0;}////////////////////////////////////////////////////////////////////////////////void UnixSocket::flush( ) throw( IOException ){  throwIfNotValid( );  throwIfNotConnected( );}////////////////////////////////////////////////////////////////////////////////UnixSocketInputStream::UnixSocketInputStream(  const p<UnixSocket>& pUnixSocket): m_pUnixSocket( pUnixSocket ){}////////////////////////////////////////////////////////////////////////////////size_t UnixSocketInputStream::available( ) throw( IOException ){  return m_pUnixSocket -> available( );}////////////////////////////////////////////////////////////////////////////////bool UnixSocketInputStream::hasBeenClosed( ) throw( IOException ){  return m_pUnixSocket -> hasBeenClosed( );}////////////////////////////////////////////////////////////////////////////////size_t UnixSocketInputStream::skip(  size_t nNoOfBytes) throw( IOException ){  return m_pUnixSocket -> skip( nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////size_t UnixSocketInputStream::read(  void*   pBuffer,  size_t  nMaxNoOfBytes) throw( IOException ){  return m_pUnixSocket -> read( pBuffer, nMaxNoOfBytes );}////////////////////////////////////////////////////////////////////////////////UnixSocketOutputStream::UnixSocketOutputStream(  const p<UnixSocket>& pUnixSocket): m_pUnixSocket( pUnixSocket ){}////////////////////////////////////////////////////////////////////////////////void UnixSocketOutputStream::write(  const void* pBuffer,  size_t      nNoOfBytes) throw( IOException ){  m_pUnixSocket -> write( pBuffer, nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////size_t UnixSocketOutputStream::rewind(  size_t nNoOfBytes) throw( IOException ){  return m_pUnixSocket -> rewind( nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////bool UnixSocketOutputStream::hasBeenClosed( ) throw( IOException ){  return m_pUnixSocket -> hasBeenClosed( );}////////////////////////////////////////////////////////////////////////////////void UnixSocketOutputStream::flush( ) throw( IOException ){  m_pUnixSocket -> flush( );}////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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