📄 udpipsck.cpp
字号:
/* ---
**
**
** This is a new connection. Look at the flags and variable names
** to see what lookups should occur and where the data is put
**
**
--- */
/* --- should this object set the PeerIP address? --- */
int iFlags = pChildData->pMainSocketData->iFlags;
/* ---
Set PeerAddress variable, if applicable
--- */
/* ---
When the hostname is unavailable jsut have it turn up blank
# define TEXT_UNAVAILABLE "** Unavailable **"
--- */
# define TEXT_UNAVAILABLE ""
if ( iFlags & FLG_SETREMOTEADDRESS )
{
/* --- set remote Address ? --- */
DBInfo *pIPInfo = pChildData->pMainSocketData->pPeerAddressVariable;
if ( pIPInfo )
{
/* ---
inet_ntoa is not thread safe, protect access to it
--- */
PIPlatform_beforeUnsafeBlock();
/* --- convert the peer ip to a string if we have the ip --- */
const char *pPeerAddress = 0;
pPeerAddress = ::inet_ntoa( pChildData->tAddr.sin_addr );
PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
pIPInfo->pFKVariableName, (void *)pPeerAddress,
pIPInfo->iFlags | PIDBFLAG_FASTKEY );
PIPlatform_afterUnsafeBlock();
};
if ( iFlags & FLG_DNSREVERSELOOKUP )
{
/* --- set remote hostname ? --- */
DBInfo *pHostInfo = pChildData->pMainSocketData->pPeerHostVariable;
if ( pHostInfo )
{
/* ---
inet_ntoa is not thread safe, protect access to it
--- */
PIPlatform_beforeUnsafeBlock();
/* --- if we have the ip structure, lookup the hostname --- */
struct hostent *pEnt;
pEnt = ::gethostbyaddr(
(const char *)&(pChildData->tAddr.sin_addr),
sizeof(pChildData->tAddr.sin_addr), AF_INET );
PIDB_add( PIObject_getDB( pNewSocket ), pHostInfo->iType,
pHostInfo->pFKVariableName,
(void *)( pEnt ? pEnt->h_name : TEXT_UNAVAILABLE ),
pHostInfo->iFlags | PIDBFLAG_FASTKEY );
PIPlatform_afterUnsafeBlock();
};
};
};
/* ---
Set LocalAddress if applicable
--- */
if ( iFlags & FLG_SETLOCALADDRESS )
{
DBInfo *pIPInfo = pChildData->pMainSocketData->pLocalAddressVariable;
if ( pIPInfo )
{
struct sockaddr_in tLocalAddr;
int iLocalSize = sizeof( struct sockaddr_in );
for(;;)
{
/* --- get local socket information --- */
if ( ::getsockname( pChildData->iSocket,
(struct sockaddr *)&tLocalAddr,
&(uint)iLocalSize )==-1 )
{
if ( errno==EINTR )
{
/* --- restart system call --- */
PIThread_userYield();
continue;
};
iLocalSize = 0; /* indicate an error */
};
break;
};
if ( iLocalSize>0 )
{
/* ---
inet_ntoa is not thread safe, protect access to it
--- */
PIPlatform_beforeUnsafeBlock();
const char *pLocalAddress = 0;
pLocalAddress = ::inet_ntoa( tLocalAddr.sin_addr );
PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
pIPInfo->pFKVariableName, (void *)pLocalAddress,
pIPInfo->iFlags | PIDBFLAG_FASTKEY );
/* ---
set ServerPort variable
--- */
DBInfo *pIPInfo = pChildData->pMainSocketData->pServerPortVariable;
if ( pIPInfo ) {
int localPort = ntohs (tLocalAddr.sin_port);
char szPort[6];
char *pPort = szPort;
sprintf(pPort, "%lu", localPort);
PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType, pIPInfo->pFKVariableName,
(void *)pPort, 0 );
};
PIPlatform_afterUnsafeBlock();
}
else
{
/* --- error --- */
STDERR << "getsockname() failed, errno#" << errno << endl;
PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
pIPInfo->pFKVariableName, (void *)"0.0.0.0",
pIPInfo->iFlags | PIDBFLAG_FASTKEY );
}; /* iLocalSize!=0 */
}; /* pIPInfo!=NULL */
}; /* iFlags & FLG_SETLOCALADDRRESS */
/* ---
Write send and receive timeout into the DB, to be overridden as
necessary
--- */
assert( pFKRecvTimeout );
assert( pFKSendTimeout );
PIDB_add( PIObject_getDB( pNewSocket ), PIDBTYPE_OPAQUE, pFKRecvTimeout,
(void *)(pChildData->pMainSocketData->iRecvTimeout), PIDBFLAG_FASTKEY );
PIDB_add( PIObject_getDB( pNewSocket ), PIDBTYPE_OPAQUE, pFKSendTimeout,
(void *)(pChildData->pMainSocketData->iSendTimeout), PIDBFLAG_FASTKEY );
/* ---
Done
--- */
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_onClassLoad
Synopsis:
Description:
This is called on program startup, restart or shutdown.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_onClassLoad( PIClass_LoadAction eAction,
void * /* pV */ )
{
#if WIN32
WSAData tWSAData;
enum { DESIRED_WINSOCK_VERSION=0x0101 };
/* enum { DESIRED_WINSOCK_VERSION=0x0200 }; */
#endif
switch( eAction )
{
case STARTUP:
#if WIN32
/*
** WSAStartup returns 0 or one of these values
**
WSASYSNOTREADY
WSAVERNOTSUPPORTED
WSAEINVAL
*/
if ( ::WSAStartup( DESIRED_WINSOCK_VERSION, &tWSAData ) )
{ return PIAPI_ABORT; };
#endif
/* ---
Get fast keys
--- */
pFKSendTimeout = PIDB_getFastKey( KEY_CONF_SENDTIMEOUT,
PIDBTYPE_OPAQUE );
pFKRecvTimeout = PIDB_getFastKey( KEY_CONF_RECVTIMEOUT,
PIDBTYPE_OPAQUE );
break;
case SHUTDOWN:
#if WIN32
WSACleanup();
#endif
break;
default:;
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_UDPIPSocket
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_UDPIPSocket(
PIObject *pObject,
int iArgc,
const char *ppArgv[]
)
{
/*
** Allocate instance data
*/
UDPIPSocketData *pData = new UDPIPSocketData( pObject, iArgc, ppArgv );
PIObject_setUserData( pObject, pData );
/*
*/
/* --- pObject is the new parent socket --- */
if ( !pData->IsOK() )
{ return PIAPI_ABORT; };
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_copyUDPIPSocket
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_copyUDPIPSocket( PIObject *pObject, int iArgc,
const char *ppArgv[] )
{
/* automatic variables */
UDPIPSocketData *pData;
UDPIPSocketData *pParentData;
/*
** Grap old user data, as pParentData
*/
pParentData = (UDPIPSocketData *)PIObject_getUserData( pObject );
/*
** Allocate instance data
*/
pData = new UDPIPSocketData( pObject, pParentData, iArgc, ppArgv );
/* ---
Is this an active or passive socket?
--- */
if ( pData->pMainSocketData->iServer )
{
/* ---
Attempt to accept a new connection on pObject socket
--- */
int iRet = pData->pMainSocketData->Accept( pParentData, pObject );
if ( iRet!=PIAPI_COMPLETED )
{ return iRet; };
}
else
{
/* ---
Attempt to make a new connection to a remote host
--- */
const char *pHostName;
int iPort;
/* ---
If not given as arguments connect to the remote host
with parameters found in the main socket data
--- */
if ( iArgc!=2 )
{
pHostName = pData->pMainSocketData->pHost;
iPort = pData->pMainSocketData->iPort;
}
else
{
pHostName = (const char *)ppArgv[0];
iPort = (int)ppArgv[1];
};
if ( Internal_connect( pObject, pHostName, iPort ) )
{
return PIAPI_ERROR;
};
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_xUDPIPSocket
Synopsis:
Description:
Destructor for instances of the UDPIPSocket class. Performs cleanup.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_xUDPIPSocket( PIObject *pObject, int,
const char *[] )
{
delete (UDPIPSocketData *)PIObject_getUserData( pObject );
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_send
Synopsis:
Description:
Send data down pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_send( PIObject *pObject, void *pData,
int iLen, int *piSent, int, const char *[] )
{
/* --- automatic variables --- */
int iRet = -1;
int iToSend=iLen;
int iSent=0;
const char *pToSend=(const char *)pData;
UDPIPSocketData *pInstanceData=
(UDPIPSocketData *)PIObject_getUserData( pObject );
assert( pToSend && pInstanceData && iToSend && piSent );
int iTimeout=(int)PIDB_lookup( PIObject_getDB( pObject ),
PIDBTYPE_OPAQUE, pFKSendTimeout, PIDBFLAG_FASTKEY );
do {
if ( PIPlatform_pollNetFD( pInstanceData->iSocket,
PIPLATFORM_POLL_WRITE,
iTimeout ) <=0 )
{ break; };
iRet=::sendto(
pInstanceData->iSocket,
&(pToSend[iSent]),
iToSend,
0,
(struct sockaddr *)&(pInstanceData->tAddr),
pInstanceData->iSize );
if ( !iRet ) break; /* connection closed */
if ( iRet==-1 )
{
if ( errno==EINTR )
{ continue; /* signal caught */ };
break;
};
iSent += iRet;
iToSend -= iRet;
}
while( iToSend>0 );
if ( iRet==-1 )
{ return PIAPI_ERROR; };
*piSent=iSent;
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: UDPIPSocket_recv
Synopsis:
Description:
Get data out of pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_recv( PIObject *pObject, void *pData,
int iLen, int *piReceived, int, const char *[] )
{
/* --- automatic variables --- */
int iRet = -1;
UDPIPSocketData *pInstanceData=
(UDPIPSocketData *)PIObject_getUserData( pObject );
assert( pInstanceData && piReceived );
/*
** Check for received data in buffer
*/
if ( pInstanceData->iReceivedLen > 0 )
{
if ( iLen < pInstanceData->iReceivedLen )
{
*piReceived = iLen;
memcpy( pData, pInstanceData->szReceived, iLen );
pInstanceData->iReceivedLen -= iLen;
}
else
{
*piReceived = pInstanceData->iReceivedLen;
memcpy( pData, pInstanceData->szReceived,
pInstanceData->iReceivedLen );
pInstanceData->iReceivedLen = 0;
};
return PIAPI_COMPLETED;
};
/*
** Read more data
*/
int iTimeout=(int)PIDB_lookup( PIObject_getDB( pObject ),
PIDBTYPE_OPAQUE, pFKRecvTimeout, PIDBFLAG_FASTKEY );
for(;;)
{
if ( PIPlatform_pollNetFD( pInstanceData->iSocket,
PIPLATFORM_POLL_READ,
iTimeout ) <=0 )
{ break; };
iRet=::recvfrom(
pInstanceData->iSocket,
(char *)pData,
iLen,
0,
(struct sockaddr *)&(pInstanceData->tAddr),
&((uint)pInstanceData->iSize) );
if ( iRet==-1 && errno==EINTR ) continue; /* signal caught */
break;
};
if ( iRet==-1 ) return PIAPI_ERROR;
*piReceived=iRet;
return PIAPI_COMPLETED;
}
/* ---
Class configuration specification
--- */
#if 0
/*___+++CNF_BEGIN+++___*/
<Class>
Name UDPIPIOClass
Type IO
Library IO
OnClassLoad UDPIPSocket_onClassLoad
Constructor UDPIPSocket_UDPIPSocket
CopyConstructor UDPIPSocket_copyUDPIPSocket
Destructor UDPIPSocket_xUDPIPSocket
Out UDPIPSocket_send
In UDPIPSocket_recv
</Class>
/*___+++CNF_END+++___*/
<Object>
Name UDPIPIOObject
Class UDPIPIOClass
BindHost localhost # host to bind to
BindPort 1200 # port to bind on
Type Passive # Passive (server) or Active (client)
AcceptTimeout 1000 # applies to Passive only
RecvTimeout 30
SendTimeout 60
PeerAddressVariable "STRING:RemoteAddr"
PeerHostNameVariable "STRING:RemoteHost"
LocalAddressVariable "STRING:LocalAddr"
ServerPortVariable "RFC822:ServerPort"
Flags "OwnDB|SetLocalAddress|SetPeerAddress|DNSReverseLookup"
</Object>
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -