📄 win32socket.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.////////////////////////////////////////////////////////////////////////////////#ifndef _WIN32#define _WIN32#endif#include <windows.h>#include <more/create.hpp>#include "win32socket.hpp"using namespace more::os::win32;////////////////////////////////////////////////////////////////////////////////Win32SocketAddress::Win32SocketAddress( struct sockaddr_in& sockAddrIn): m_sockAddrIn( sockAddrIn ){}////////////////////////////////////////////////////////////////////////////////void Win32SocketAddress::resolve( const String& sNameOfHost, int nNoOfPort) throw( IOException ){ m_sockAddrIn.sin_family = PF_INET; m_sockAddrIn.sin_addr.s_addr = inet_addr( sNameOfHost ); m_sockAddrIn.sin_port = htons( ( u_short ) nNoOfPort ); if( m_sockAddrIn.sin_addr.s_addr == INADDR_NONE ) { struct hostent* pHost = gethostbyname( sNameOfHost ); for( int i = 0; pHost == 0 && WSAGetLastError( ) == WSATRY_AGAIN && i < 8; i++ ) { pHost = gethostbyname( sNameOfHost ); } if( pHost == 0 ) { throw IOException( WSAGetLastError( ), "Could not resolve name of host" ); } memcpy( &m_sockAddrIn.sin_addr, pHost -> h_addr, pHost -> h_length ); }}////////////////////////////////////////////////////////////////////////////////Win32AcceptorSocket::Win32AcceptorSocket( ){ m_socket = socket( PF_INET, SOCK_STREAM, 0 ); m_nNoOfPort = -1; m_bHasBeenCancelled = false;}////////////////////////////////////////////////////////////////////////////////void Win32AcceptorSocket::finalize( ){ if( isValid( ) ) { close( ); }}////////////////////////////////////////////////////////////////////////////////bool Win32AcceptorSocket::isValid( ) const{ return m_socket != -1;}////////////////////////////////////////////////////////////////////////////////void Win32AcceptorSocket::bind( const String& sNameOfHost, size_t nNoOfPort) throw( IOException ){ int nResult = 0; throwIfNotValid( ); 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 { Win32SocketAddress address( m_sockAddrIn ); address.resolve( sNameOfHost, nNoOfPort ); } nResult = ::bind( m_socket, ( const sockaddr* ) &m_sockAddrIn, sizeof( sockaddr_in ) ); if( nResult == 0 ) { int 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( WSAGetLastError( ), "Unable to bind socket" ); }}////////////////////////////////////////////////////////////////////////////////void Win32AcceptorSocket::bind( size_t nNoOfPort) throw( IOException ){ bind( "", nNoOfPort );}////////////////////////////////////////////////////////////////////////////////String Win32AcceptorSocket::getNameOfHost( ) const{ char sNameOfHost[512]; gethostname( sNameOfHost, 511 ); return sNameOfHost;}////////////////////////////////////////////////////////////////////////////////size_t Win32AcceptorSocket::getNoOfPort( ) const{ return m_nNoOfPort;}////////////////////////////////////////////////////////////////////////////////p<Socket> Win32AcceptorSocket::accept( ) throw( IOException ){ throwIfNotValid( ); p<Socket> pResult; int nResultOfListen = -1; SOCKET socket = -1; struct sockaddr_in sockAddrIn; int sizeOfSockAddrIn = sizeof( sockaddr_in ); nResultOfListen = ::listen( m_socket, 1 ); if( nResultOfListen < 0 ) { throw IOException( WSAGetLastError( ), "Error while listening to socket" ); } socket = ::accept( m_socket, ( sockaddr* ) &sockAddrIn, &sizeOfSockAddrIn ); if( !m_bHasBeenCancelled ) { if( socket == -1 ) { throw IOException( WSAGetLastError( ), "Error while accepting socket" ); } pResult = CREATE Win32Socket( socket, sockAddrIn ); } return pResult;}////////////////////////////////////////////////////////////////////////////////void Win32AcceptorSocket::cancel( ) throw( IOException ){ throwIfNotValid( ); m_bHasBeenCancelled = true; ::closesocket( m_socket ); m_socket = -1;}////////////////////////////////////////////////////////////////////////////////void Win32AcceptorSocket::close( ) throw( IOException ){ if( m_bHasBeenCancelled ) { m_bHasBeenCancelled = false; } else { throwIfNotValid( ); ::closesocket( m_socket ); m_socket = -1; }}////////////////////////////////////////////////////////////////////////////////Win32Socket::Win32Socket( ){ m_socket = socket( PF_INET, SOCK_STREAM, 0 ); m_bHasBeenConnected = false;}////////////////////////////////////////////////////////////////////////////////Win32Socket::Win32Socket( SOCKET socket, sockaddr_in& sockAddrIn): m_socket( socket ), m_sockAddrIn( sockAddrIn ){ m_bHasBeenConnected = true;}////////////////////////////////////////////////////////////////////////////////void Win32Socket::finalize( ){ if( isValid( ) ) { close( ); }}////////////////////////////////////////////////////////////////////////////////bool Win32Socket::isValid( ) const{ return m_socket != -1;}////////////////////////////////////////////////////////////////////////////////void Win32Socket::connect( const String& sNameOfHost, size_t nNoOfPort) throw( IOException ){ throwIfNotValid( ); Win32SocketAddress 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( WSAGetLastError( ), "Unable to connect to socket" ); } m_bHasBeenConnected = true;}////////////////////////////////////////////////////////////////////////////////String Win32Socket::getNameOfHost( ) const{ int nErrorCode; sockaddr_in address; int nSizeOfBuffer = sizeof( address ); nErrorCode = getpeername( m_socket, ( struct sockaddr* ) &address, &nSizeOfBuffer ); if( nErrorCode != 0 ) { throw IOException( nErrorCode, "Win32Socket::getNameOfHost failed" ); } return inet_ntoa( address.sin_addr );}////////////////////////////////////////////////////////////////////////////////size_t Win32Socket::getNoOfPort( ) const{ return m_sockAddrIn.sin_port;}////////////////////////////////////////////////////////////////////////////////p<InputStream> Win32Socket::getInputStream( ) throw( IOException ){ throwIfNotValid( ); return CREATE Win32SocketInputStream( this );}////////////////////////////////////////////////////////////////////////////////p<OutputStream> Win32Socket::getOutputStream( ) throw( IOException ){ throwIfNotValid( ); return CREATE Win32SocketOutputStream( this );}////////////////////////////////////////////////////////////////////////////////void Win32Socket::close( ) throw( IOException ){ throwIfNotValid( ); m_bHasBeenConnected = false; ::closesocket( m_socket ); m_socket = -1;}////////////////////////////////////////////////////////////////////////////////size_t Win32Socket::available( ) throw( IOException ){ throwIfNotConnected( ); return 0;}////////////////////////////////////////////////////////////////////////////////bool Win32Socket::hasBeenClosed( ) throw( IOException ){ throwIfNotConnected( ); return m_socket == -1;}////////////////////////////////////////////////////////////////////////////////size_t Win32Socket::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 Win32Socket::read( void* pBuffer, size_t nMaxNoOfBytes) throw( IOException ){ int nNoOfReceivedBytes; throwIfNotValid( ); throwIfNotConnected( ); nNoOfReceivedBytes = recv( m_socket, ( char* ) pBuffer, nMaxNoOfBytes, 0 ); if( nNoOfReceivedBytes < 0 ) { throw IOException( WSAGetLastError( ), "Error while reading from socket" ); } return ( size_t ) nNoOfReceivedBytes;}////////////////////////////////////////////////////////////////////////////////void Win32Socket::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( WSAGetLastError( ), "Error while writing to socket" ); }}////////////////////////////////////////////////////////////////////////////////size_t Win32Socket::rewind( size_t nNoOfBytes) throw( IOException ){ throw IOException( 0, "Rewind on this output-stream not supported" ); return 0;}////////////////////////////////////////////////////////////////////////////////void Win32Socket::flush( ) throw( IOException ){ throwIfNotValid( ); throwIfNotConnected( );}////////////////////////////////////////////////////////////////////////////////Win32SocketInputStream::Win32SocketInputStream( p<Win32Socket> pWin32Socket): m_pWin32Socket( pWin32Socket ){}////////////////////////////////////////////////////////////////////////////////size_t Win32SocketInputStream::available( ) throw( IOException ){ return m_pWin32Socket -> available( );}////////////////////////////////////////////////////////////////////////////////bool Win32SocketInputStream::hasBeenClosed( ) throw( IOException ){ return m_pWin32Socket -> hasBeenClosed( );}////////////////////////////////////////////////////////////////////////////////size_t Win32SocketInputStream::skip( size_t nNoOfBytes) throw( IOException ){ return m_pWin32Socket -> skip( nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////size_t Win32SocketInputStream::read( void* pBuffer, size_t nMaxNoOfBytes) throw( IOException ){ return m_pWin32Socket -> read( pBuffer, nMaxNoOfBytes );}////////////////////////////////////////////////////////////////////////////////Win32SocketOutputStream::Win32SocketOutputStream( p<Win32Socket> pWin32Socket): m_pWin32Socket( pWin32Socket ){}////////////////////////////////////////////////////////////////////////////////void Win32SocketOutputStream::write( const void* pBuffer, size_t nNoOfBytes) throw( IOException ){ m_pWin32Socket -> write( pBuffer, nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////size_t Win32SocketOutputStream::rewind( size_t nNoOfBytes) throw( IOException ){ return m_pWin32Socket -> rewind( nNoOfBytes );}////////////////////////////////////////////////////////////////////////////////bool Win32SocketOutputStream::hasBeenClosed( ) throw( IOException ){ return m_pWin32Socket -> hasBeenClosed( );}////////////////////////////////////////////////////////////////////////////////void Win32SocketOutputStream::flush( ) throw( IOException ){ m_pWin32Socket -> flush( );}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -