📄 macossocket.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 <MacHeadersPPC>#include <OpenTransport.h>#include <OpenTptInternet.h>#include <stdio.h>#include <more/create.hpp>#include "macossocket.hpp"using namespace more::macos;////////////////////////////////////////////////////////////////////////////////static pascal void yieldFromSyncOTCall( void* pIgnore, OTEventCode nCode, OTResult nResult, void* pIgnoreToo){ if( nCode == kOTSyncIdleEvent ) { YieldToAnyThread( ); } else { OTEventCode nDummy = nCode; }}////////////////////////////////////////////////////////////////////////////////inline void prepareEndpoint( EndpointRef pEndpoint){ OTSetSynchronous( pEndpoint ); OTSetBlocking( pEndpoint ); OTInstallNotifier( pEndpoint, yieldFromSyncOTCall, 0 ); OTUseSyncIdleEvents( pEndpoint, true );}////////////////////////////////////////////////////////////////////////////////inline OTResult handleOTLook( EndpointRef pEndpoint){ OTResult nResult = OTLook( pEndpoint ); switch( nResult ) { case T_DISCONNECT: { nResult = OTRcvDisconnect( pEndpoint, 0 ); break; } case T_ORDREL: { nResult = OTRcvOrderlyDisconnect( pEndpoint ); if( nResult == noErr ) { nResult = OTSndOrderlyDisconnect( pEndpoint ); } break; } default: { break; } } return nResult;}////////////////////////////////////////////////////////////////////////////////MacOSAcceptorSocket::MacOSAcceptorSocket( ){ OTConfiguration* pOTConfiguration = OTCreateConfiguration( "tilisten,tcp" ); OSStatus nStatusCode; m_pEndpoint = OTOpenEndpoint( pOTConfiguration, 0, 0, &nStatusCode ); if( m_pEndpoint != kOTInvalidEndpointRef && nStatusCode == noErr ) { prepareEndpoint( m_pEndpoint ); } m_nNoOfPort = 0; m_bHasBeenBound = false; m_bHasBeenCancelled = false; m_bIsBlockingInListen = false;}////////////////////////////////////////////////////////////////////////////////bool MacOSAcceptorSocket::isValid( ) const{ return m_pEndpoint != kOTInvalidEndpointRef;}////////////////////////////////////////////////////////////////////////////////void MacOSAcceptorSocket::bind( const String& sNetMask, size_t nNoOfPort) throw( IOException ){ OSStatus nStatusCode; TBind bindRequest1; throwIfNotValid( ); m_ipAddress.fAddressType = AF_INET; m_ipAddress.fHost = 0; if( nNoOfPort > 0 ) { m_ipAddress.fPort = ( unsigned short ) nNoOfPort; } else { m_ipAddress.fPort = kOTAnyInetAddress; } bindRequest1.addr.buf = ( UInt8* ) &m_ipAddress; bindRequest1.addr.len = sizeof( InetAddress ); bindRequest1.qlen = 1; nStatusCode = OTBind( m_pEndpoint, &bindRequest1, 0 ); if( nStatusCode == noErr ) { TBind bindRequest2; InetAddress protAddress; bindRequest2.addr.buf = ( UInt8* ) &protAddress; bindRequest2.addr.len = sizeof( InetAddress ); bindRequest2.qlen = 1; nStatusCode = OTGetProtAddress( m_pEndpoint, &bindRequest2, 0 ); if( nStatusCode == noErr ) { m_nNoOfPort = protAddress.fPort; } else { OTUnbind( m_pEndpoint ); } } if( nStatusCode != noErr ) { throw IOException( nStatusCode, "Unable to bind socket" ); } m_bHasBeenBound = true;}////////////////////////////////////////////////////////////////////////////////void MacOSAcceptorSocket::bind( size_t nNoOfPort) throw( IOException ){ bind( "", nNoOfPort );}////////////////////////////////////////////////////////////////////////////////String MacOSAcceptorSocket::getNameOfHost( ) const{ char sNameOfHost[128] = { '\0' }; OSStatus nStatusCode; InetInterfaceInfo interfaceInfo; nStatusCode = OTInetGetInterfaceInfo( &interfaceInfo, kDefaultInetInterface ); if( nStatusCode == noErr ) { unsigned char* pIPAddress = ( unsigned char* ) &interfaceInfo.fAddress; sprintf( sNameOfHost, "%d.%d.%d.%d", ( int ) pIPAddress[0], ( int ) pIPAddress[1], ( int ) pIPAddress[2], ( int ) pIPAddress[3] ); } return sNameOfHost;}////////////////////////////////////////////////////////////////////////////////size_t MacOSAcceptorSocket::getNoOfPort( ) const{ return m_nNoOfPort;}////////////////////////////////////////////////////////////////////////////////p<Socket> MacOSAcceptorSocket::accept( ) throw( IOException ){ p<Socket> pResult; TCall call; OSStatus nStatusCode; throwIfNotValid( ); if( m_bHasBeenCancelled ) { throw IOException( -1, "Socket has already been cancelled" ); } OTMemzero( &call, sizeof( TCall ) ); call.addr.buf = ( UInt8* ) &m_ipAddress; call.addr.maxlen = sizeof( InetAddress ); m_bIsBlockingInListen = true; nStatusCode = OTListen( m_pEndpoint, &call ); m_bIsBlockingInListen = false; if( nStatusCode != userCanceledErr ) { OTConfiguration* pOTConfiguration; EndpointRef pEndpoint; if( nStatusCode != noErr ) { throw IOException( nStatusCode, "Error while listening to socket" ); } pOTConfiguration = OTCreateConfiguration( "tcp" ); pEndpoint = OTOpenEndpoint( pOTConfiguration, 0, nil, &nStatusCode ); if( nStatusCode != noErr ) { throw IOException( nStatusCode, "Error while creating accepting socket" ); } prepareEndpoint( pEndpoint ); nStatusCode = OTAccept( m_pEndpoint, pEndpoint, &call ); if( nStatusCode == kOTLookErr ) { handleOTLook( m_pEndpoint ); } if( nStatusCode != noErr ) { nStatusCode = OTCloseProvider( m_pEndpoint ); throw IOException( nStatusCode, "Error while accepting connection" ); } pResult = CREATE MacOSSocket( pEndpoint ); } return pResult;}////////////////////////////////////////////////////////////////////////////////void MacOSAcceptorSocket::cancel( ) throw( IOException ){ throwIfNotValid( ); if( OTIsBlocking( m_pEndpoint ) && m_bIsBlockingInListen ) { OSStatus nStatusCode = OTCancelSynchronousCalls( m_pEndpoint, userCanceledErr ); if( nStatusCode != noErr ) { throw IOException( nStatusCode, "Error while cancelling accept call" ); } } m_bHasBeenCancelled = true;}////////////////////////////////////////////////////////////////////////////////void MacOSAcceptorSocket::close( ) throw( IOException ){ OSStatus nStatusCode; throwIfNotValid( ); if( m_bHasBeenBound ) { nStatusCode = OTUnbind( m_pEndpoint ); m_bHasBeenBound = false; } nStatusCode = OTCloseProvider( m_pEndpoint ); m_pEndpoint = kOTInvalidEndpointRef;}////////////////////////////////////////////////////////////////////////////////void MacOSAcceptorSocket::finalize( ){ if( isValid( ) ) { close( ); }}////////////////////////////////////////////////////////////////////////////////MacOSSocket::MacOSSocket( ){ OTConfiguration* pOTConfiguration = OTCreateConfiguration( "tcp" ); OSStatus nStatusCode; m_pEndpoint = OTOpenEndpoint( pOTConfiguration, 0, 0, &nStatusCode ); if( m_pEndpoint != kOTInvalidEndpointRef && nStatusCode == noErr ) { prepareEndpoint( m_pEndpoint ); } m_bHasBeenBound = false; m_bHasBeenConnected = false;}////////////////////////////////////////////////////////////////////////////////MacOSSocket::MacOSSocket( EndpointRef pEndpoint){ m_pEndpoint = pEndpoint; m_bHasBeenBound = false; m_bHasBeenConnected = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -