#include "fwce.ch"
#include "winapi.ch"
#define AF_INET 2
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define IPPROTO_IP 0
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_UDP 17 /* user datagram protocol */
#define SOL_SOCKET -1
#define SO_BROADCAST 32
#define FD_READ 1
#define FD_WRITE 2
#define FD_OOB 4
#define FD_ACCEPT 8
#define FD_CONNECT 16
#define FD_CLOSE 32
#define SO_REUSEADDR 4
#define FILE_BLOCK 4096
#define WSAEWOULDBLOCK 10035
#ifdef __XPP__
#define New _New
#endif
//----------------------------------------------------------------------------//
CLASS TSocket
DATA nPort AS NUMERIC INIT 0 // socket port number
DATA cIPAddr AS String INIT "" // socket IP address
DATA nTimeOut AS NUMERIC INIT 30
DATA nBackLog AS NUMERIC INIT 5
DATA nSocket AS NUMERIC INIT -1
DATA hFile AS NUMERIC INIT 0
DATA nDelay AS NUMERIC INIT 0
DATA nRetry AS NUMERIC INIT 0
DATA nMaxRetry AS NUMERIC INIT 10
DATA bAccept, bRead, bWrite, bClose, bConnect, bOOB
DATA lDebug
DATA cLogFile
DATA oTimer
DATA cMsg, nRetCode, Cargo
DATA aBuffer // data sending buffer
DATA lSending // sending in progress
DATA lFileSend
DATA cType
CLASSDATA aSockets INIT {}
METHOD New( nPort, cType, cUserAddr ) CONSTRUCTOR
MESSAGE Accept METHOD _Accept( nSocket )
METHOD End()
METHOD HandleEvent( nSocket, nOperation, nErrorCode )
METHOD GetData()
METHOD SendBin( pMemory, nSize ) INLINE SendBinary( pMemory, nSize )
METHOD SendChunk( nBlockSize )
METHOD SendFile( cFileName, nBlockSize )
METHOD SendData( cData )
METHOD UdpSend( cData, cIpAddr, nPort )
MESSAGE Listen METHOD _Listen()
METHOD Close()
METHOD CloseAll() // New
METHOD Connect( cIPAddr, nPort ) //INLINE ;
//ConnectTo( ::nSocket, If( nPort != nil, nPort, ::nPort ), cIPAddr )
METHOD OnAccept() INLINE If( ::bAccept != nil, Eval( ::bAccept, Self ),)
METHOD OnRead() INLINE If( ::bRead != nil, Eval( ::bRead, Self ),)
METHOD OnWrite() INLINE If( ::bWrite != nil, Eval( ::bWrite, Self ),)
METHOD OnClose() INLINE If( ::bClose != nil, Eval( ::bClose, Self ),)
METHOD OnConnect( nErrorCode ) INLINE If( ::bConnect != nil, Eval( ::bConnect, Self, nErrorCode ),)
METHOD OnOOB() INLINE If( ::bOOB != nil, Eval( ::bOOB, Self ),)
METHOD ClientIP() INLINE GetPeerName( ::nSocket )
METHOD SktTimer() INLINE NIL
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( nPort, cType, cUserAddr, oMWnd ) CLASS TSocket
LOCAL oWndMain
DEFAULT ::aSockets := {}, cType := "TCP", cUserAddr := ""
::cType := cType
if Len( ::aSockets ) == 0
if WSAStartup() != 0
MsgAlert( "WSAStartup error" )
endif
endif
if ( ::nSocket := Socket( AF_INET, iif( cType == "TCP", SOCK_STREAM, SOCK_DGRAM ), IPPROTO_IP ) ) == 0
MsgAlert( "Socket creation error: " + Str( WsaGetLastError() ) )
endif
::cIPAddr := HB_GetHostByName( GetHostName() )
::aBuffer := {}
::lSending := .F.
::lFileSend := .F.
::lDebug := .F.
if nPort != nil
::nPort := nPort
if cUserAddr != NIL .and. !Empty( cUserAddr ) // nbs 2005.05.13
BindToAddr( ::nSocket, nPort, cUserAddr )
else
BindToPort( ::nSocket, nPort ) // Bind is not needed for connect sockets
endif
endif
AAdd( ::aSockets, Self )
oWndMain := WndMain()
if !( oWndMain == NIL )
oWndMain:bSocket = { | nSocket, nLParam | ::HandleEvent( nSocket,;
nLoWord( nLParam ), nHiWord( nLParam ) ) }
WSAAsyncSelect( ::nSocket, oWndMain:hWnd, WM_ASYNCSELECT,;
nOr( FD_ACCEPT, FD_OOB, FD_READ, FD_CLOSE, FD_CONNECT, FD_WRITE ) )
endif
return Self
//---------------------------------------------------------------------------//
METHOD _Accept( nSocket ) CLASS TSocket
::nSocket := Accept( nSocket )
::aBuffer := {}
::lSending := .F.
::lFileSend := .F.
::lDebug := .F.
::cType := "TCP"
AAdd( ::aSockets, Self )
WSAAsyncSelect( ::nSocket, WndMain():hWnd, WM_ASYNCSELECT,;
nOr( FD_ACCEPT, FD_OOB, FD_READ, FD_CLOSE, FD_CONNECT, FD_WRITE ) )
return Self
//----------------------------------------------------------------------------//
METHOD Connect( cIPAddr ) CLASS TSocket
DEFAULT cIPAddr := ::cIPAddr
cIPAddr = If( IsAlpha( cIPAddr ), HB_GetHostByName( AllTrim( cIPAddr ) ), cIPAddr )
ConnectTo( ::nSocket, ::nPort, cIPAddr )
return nil
//----------------------------------------------------------------------------//
METHOD GetData( cUdpAddr, nPort ) CLASS TSocket
LOCAL cData := ""
if ::cType == "TCP"
::nRetCode := Recv( ::nSocket, @cData )
else
::nRetCode := RecvUdp( ::nSocket, @cData, @cUdpAddr, @nPort )
endif
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { cData } )
endif
return cData
//----------------------------------------------------------------------------//
METHOD _Listen() CLASS TSocket
LOCAL nRetCode := Listen( ::nSocket, ::nBackLog )
return ( nRetCode == 0 )
//----------------------------------------------------------------------------//
METHOD End() CLASS TSocket
LOCAL nAt := AScan( ::aSockets, { | oSocket | oSocket:nSocket == ::nSocket } )
LOCAL nCount := 0
while ::lSending
SysRefresh()
if !::lFileSend
nCount++
if nCount > 65535
Exit
endif
endif
end
if nAt != 0
ADel( ::aSockets, nAt )
ASize( ::aSockets, Len( ::aSockets ) - 1 )
if Len( ::aSockets ) == 0
WSACleanUp()
endif
endif
if ! Empty( ::nSocket )
CloseSocket( ::nSocket )
::nSocket = 0
endif
return nil
//----------------------------------------------------------------------------//
METHOD Close() CLASS TSocket
LOCAL nCount := 0
while ::lSending
SysRefresh()
if !::lFileSend
nCount++
if nCount > 65535
Exit
endif
endif
end
return CloseSocket( ::nSocket )
//----------------------------------------------------------------------------//
METHOD CloseAll() CLASS TSocket
LOCAL i
LOCAL nLen := Len( ::aSockets )
if nLen > 0
for i := 1 To nLen
CloseSocket( ::aSockets[i]:nSocket )
next
WSACleanUp()
::aSockets := {}
endif
Return NIL
//---------------------------------------------------------------------------//
METHOD HandleEvent( nSocket, nOperation, nErrorCode ) CLASS TSocket
local nAt := AScan( ::aSockets, { | oSocket | oSocket:nSocket == nSocket } )
local oSocket
if nAt != 0
oSocket = ::aSockets[ nAt ]
do case
case nOperation == FD_ACCEPT
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Accept",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnAccept()
case nOperation == FD_READ
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Read",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnRead()
case nOperation == FD_WRITE
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Write",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnWrite()
case nOperation == FD_CLOSE
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Close",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnClose()
case nOperation == FD_CONNECT
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Connect",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnConnect( nErrorCode )
case nOperation == FD_OOB
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "OOB",;
"Socket handle:" + Str( nSocket ) } )
endif
oSocket:OnOOB()
otherwise
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "nOperation not recognized",;
Str( nOperation ) } )
endif
endcase
endif
return nil
//----------------------------------------------------------------------------//
METHOD SendChunk( nBlockSize ) CLASS TSocket
LOCAL cBuffer, nBytes := 0
DEFAULT nBlockSize := FILE_BLOCK
cBuffer = Space( nBlockSize )
if ::hFile != 0
nBytes = FRead( ::hFile, @cBuffer, nBlockSize )
if nBytes < nBlockSize
cBuffer = SubStr( cBuffer, 1, nBytes )
FClose( ::hFile )
::hFile = 0
endif
::SendData( cBuffer )
end
return nBytes
//----------------------------------------------------------------------------//
METHOD SendFile( cFileName, nBlockSize ) CLASS TSocket
DEFAULT nBlockSize := FILE_BLOCK
if ! Empty( cFileName ) .and. File( cFileName )
If( ( ::hFile := FOpen( cFileName ) ) != -1 )
::lFileSend := .T.
while ::SendChunk( nBlockSize ) == nBlockSize
end
::lFileSend := .F.
endif
endif
return nil
//----------------------------------------------------------------------------//
METHOD SendData( cData ) CLASS TSocket
LOCAL nSize := Len( cData )
LOCAL nLen := nSize
LOCAL nSent := 0
LOCAL nCount := 0
LOCAL nRetry := 0
if !::lSending
::lSending = .T.
else
AAdd( ::aBuffer, cData )
return nSize
endif
while ( ( nLen > 0 .and. ;
( nSent := SocketSend( ::nSocket, cData ) ) < nLen ) .or. ;
Len( ::aBuffer ) > 0 ) .and. nRetry <= ::nMaxRetry
if ::lDebug .and. ! Empty( ::cLogFile ) .and. nSent > -1
LogFile( ::cLogFile, { "Sent:", nSent, "Len:", Len( cData ), "Buffer Len:", Len( ::aBuffer ), ::nRetry } )
endif
// Check for buffered packets to send
if nLen == 0 .and. Len( ::aBuffer ) > 0
cData = ::aBuffer[ 1 ]
ADel( ::aBuffer, 1 )
ASize( ::aBuffer, Len( ::aBuffer ) - 1 )
endif
if nSent != -1
cData = SubStr( cData, nSent + 1 )
nLen = Len( cData )
else
if WSAGetLastError() != WSAEWOULDBLOCK .and. WSAGetLastError() != 0
exit
else
//Sleep( ::nDelay )
SysRefresh()
nRetry++
if nRetry >= ::nMaxRetry
nRetry = 0
exit
endif
Loop
endif
endif
SysRefresh()
if !::lFileSend
nCount++
if nCount > 65535
Exit
endif
endif
end
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { cData } )
endif
::lSending := .F.
return nSize
//----------------------------------------------------------------------------//
METHOD UdpSend( cData, cIpAddr, nPort ) CLASS TSocket
LOCAL nSize := Len( cData )
LOCAL nLen := nSize
LOCAL nSent := 0
LOCAL nCount := 0
if ! ::lSending
::lSending = .t.
else
AAdd( ::aBuffer, cData )
return nSize
endif
while ( nLen > 0 .and. ;
( nSent := SendUdp( ::nSocket, cData, cIPAddr, nPort ) ) < nLen ) .or. ;
Len( ::aBuffer ) > 0
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "Sent:", nSent, "Len:", Len( cData ), "Buffer Len:", Len( ::aBuffer ) } )
endif
// Check for buffered packets to send
if nLen == 0 .and. Len( ::aBuffer ) > 0
cData = ::aBuffer[ 1 ]
ADel( ::aBuffer, 1 )
ASize( ::aBuffer, Len( ::aBuffer ) - 1 )
endif
if nSent != -1
cData = SubStr( cData, nSent + 1 )
nLen = Len( cData )
else
if WSAGetLastError() != WSAEWOULDBLOCK
exit
endif
endif
SysRefresh()
if !::lFileSend
nCount++
if nCount > 65535
Exit
endif
endif
end
if ::lDebug .and. ! Empty( ::cLogFile )
LogFile( ::cLogFile, { "SENDUDP", cData } )
endif
::lSending := .F.
Return nSize
//---------------------------------------------------------------------------//
Function CySocketSend( nSocket, cData )
LOCAL nLen := Len( cData )
LOCAL nSend := 0
LOCAL nCount := 0
while ( nSend := SocketSend( nSocket, cData ) ) < nLen
if nSend > -1 .and. nSend < nLen
cData := SubStr( cData, nSend + 1 )
nLen := Len( cData )
else
if nSend == -1
if WSAGetLastError() != 10035
Exit
else
nCount++
if nCount > 64
Exit
endif
endif
endif
endif
SysRefresh()
end
Return( iif( nSend == -1, .F., .T. ) )
//---------------------------------------------------------------------------//
#pragma BEGINDUMP
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbdefs.h"
#include "windows.h"
#include <Windows.h>
#include <WinSock2.h>
/*
int FAR PASCAL WSAAsyncSelect(
IN SOCKET s,
IN HWND hWnd,
IN u_int wMsg,
IN long lEvent
);
HB_FUNC( WSASTARTUP )
{
WSADATA wsa;
hb_retni( WSAStartup( MAKEWORD(2,2), &wsa ) );
// hb_retni( WSAStartup( 0x202, &wsa ) );
// hb_retni( WSAStartup( 0x101, &wsa ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( WSAASYNCSELECT ) // ( nSocket, nHWnd, nMsg, nModes ) --> nReturn
{
hb_retni( WSAAsyncSelect( hb_parni( 1 ), ( HWND ) hb_parnl( 2 ), hb_parni( 3 ),
hb_parnl( 4 ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( WSAGETLASTERROR ) // () --> nError
{
hb_retni( WSAGetLastError() );
}
//----------------------------------------------------------------------------//
HB_FUNC( WSACLEANUP )
{
hb_retni( WSACleanup() );
}
//---------------------------------------------------------------------------//
HB_FUNC( GETHOSTNAME ) // () --> cHostName
{
char Name[ 255 ];
gethostname( ( char * ) Name, 255 ); // UNICODE not used here
hb_retc( ( char * ) Name );
}
//---------------------------------------------------------------------------//
HB_FUNC( GETHOSTBYNAME ) // ( cName ) --> cIPAddress
{
struct hostent * pHost;
char addr[ 20 ];
strcpy( ( char * ) addr, "0.0.0.0" );
if(( pHost = gethostbyname( hb_parc(1) ) ) != NULL )
{
sprintf( ( char * ) addr, "%i.%i.%i.%i",
( BYTE ) pHost->h_addr[ 0 ], ( BYTE ) pHost->h_addr[ 1 ],
( BYTE ) pHost->h_addr[ 2 ], ( BYTE ) pHost->h_addr[ 3 ] );
}
hb_retc( ( char * ) addr );
}
//---------------------------------------------------------------------------//
HB_FUNC( SOCKET ) // ( nAf, nType, nProtocol ) --> nSocket
{
hb_retnl( socket( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( BINDTOPORT ) // nSocket, nPort, nAddr1, nAddr2, nAddr3, nAddr4 --> lSuccess
{
struct sockaddr_in sa; // sockaddr_in sa;
// memset( ( char * ) &sa, 0, sizeof( sa ) ); // _bset
memset( &sa, 0, sizeof( sa ) ); // _bset
sa.sin_family = AF_INET;
sa.sin_port = htons( hb_parni( 2 ) );
//sa.sin_addr.s_net = _parni( 3 );
//sa.sin_addr.s_host = _parni( 4 );
//sa.sin_addr.s_lh = _parni( 5 );
//sa.sin_addr.s_impno = _parni( 6 );
sa.sin_addr.s_addr = htonl( INADDR_ANY );
hb_retl( bind( hb_parni( 1 ), ( struct sockaddr * ) &sa, sizeof( sa ) ) == 0 );
}
//----------------------------------------------------------------------------//
HB_FUNC( LISTEN ) // nSocket, nBackLog --> nResult
{
hb_retni( listen( hb_parni( 1 ), hb_parni( 2 ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( ACCEPT ) // nSocket --> nResult
{
struct sockaddr_in sa; // sockaddr_in sa;
int iLen = sizeof( sa );
sa.sin_family = AF_INET;
sa.sin_port = 0;
sa.sin_addr.s_net = 0;
sa.sin_addr.s_host = 0;
sa.sin_addr.s_lh = 0;
sa.sin_addr.s_impno = 0;
hb_retni( accept( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( CLOSESOCKET ) // ( nSocket ) --> nResult
{
hb_retni( closesocket( hb_parni( 1 ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( RECV ) // nSocket --> cResult
{
LPBYTE buffer = ( LPBYTE ) hb_xgrab( 8192 );
WORD wLen = recv( hb_parni( 1 ), ( char * ) buffer, 8192, 0 );
if( wLen < 10000 ) // socket errors = 10000 + ...
hb_storclen( ( char * ) buffer, wLen, 2 );
else
hb_storclen( "", 0, 2 );
hb_retni( wLen );
hb_xfree( buffer );
}
//---------------------------------------------------------------------------//
HB_FUNC( SOCKETSEND ) // nSocket, cText --> nResult
{
int wLen = hb_parclen( 2 );
if( wLen > 32350 )
wLen = 32350;
hb_retni( send( hb_parni( 1 ), hb_parc( 2 ), wLen, 0 ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( SENDBINARY ) // nSocket, pMemory --> nResult
{
int wLen = hb_parnl( 3 );
if( wLen > 32350 )
wLen = 32350;
hb_retni( send( hb_parni( 1 ), ( char * ) hb_parnl( 2 ), wLen, 0 ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( CONNECTTO ) // nSocket, nPort, cIPAddr --> lSuccess
{
struct sockaddr_in sa; // sockaddr_in sa;
memset( &sa, 0, sizeof( sa ) ); // _bset
sa.sin_family = AF_INET;
sa.sin_port = htons( hb_parni( 2 ) );
sa.sin_addr.s_addr = inet_addr( hb_parc( 3 ) );
hb_retl( connect( hb_parnl(1), ( struct sockaddr * )&sa, sizeof( sa ) ) == 0 );
}
//---------------------------------------------------------------------------//
HB_FUNC( SETSOCKOPT ) // int socket, int level, int optName, const void * optVal, unsigned int * optlen
{
hb_retl( setsockopt( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ),
( char * ) hb_parnl( 4 ), sizeof( hb_parnl( 4 ) ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( GETPEERNAME ) // ( nSocket )
{
struct sockaddr_in sa; // sockaddr_in sa;
int iLen = sizeof( sa );
memset( &sa, 0, sizeof( sa ) ); // _bset
getpeername( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen );
hb_retc( inet_ntoa( sa.sin_addr ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( INET_ADDR ) // cIPAddress --> nAddress
{
hb_retnl( inet_addr( hb_parc( 1 ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( GETPORT ) // nSocket
{
struct sockaddr_in sa;
int iLen = sizeof( sa );
memset( &sa, 0, sizeof( sa ) ); // _bset
getsockname( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen );
hb_retni( ntohs( sa.sin_port ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( GETIP ) // nSocket
{
struct sockaddr_in sa;
int iLen = sizeof( sa );
memset( &sa, 0, sizeof( sa ) ); // _bset
getsockname( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen );
hb_retc( inet_ntoa( sa.sin_addr ) );
}
//----------------------------------------------------------------------------//
*/
HB_FUNC( HB_GETHOSTBYNAME ) // ( cName ) --> cIPAddress
{
struct hostent * pHost;
char addr[ 20 ];
strcpy( ( char * ) addr, "0.0.0.0" );
if(( pHost = gethostbyname( hb_parc(1) ) ) != NULL )
{
sprintf( ( char * ) addr, "%i.%i.%i.%i",
( BYTE ) pHost->h_addr[ 0 ], ( BYTE ) pHost->h_addr[ 1 ],
( BYTE ) pHost->h_addr[ 2 ], ( BYTE ) pHost->h_addr[ 3 ] );
}
hb_retc( ( char * ) addr );
}
//---------------------------------------------------------------------------//
HB_FUNC( SENDUDP )
{
struct sockaddr_in sa ;
int wLen = hb_parclen( 2 );
memset( &sa, 0, sizeof( sa ) ); // _bset
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr( hb_parc( 3 ) ); // INADDR_BROADCAST ;
sa.sin_port = htons( hb_parni( 4 ) );
hb_retni( sendto( hb_parni( 1 ), hb_parc( 2 ), wLen, 0,
( struct sockaddr * ) &sa, sizeof( sa ) ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( RECVUDP )
{
struct sockaddr_in sa;
LPBYTE buffer = malloc( 8192 ) ;
int nLen = sizeof( sa );
int wLen;
memset( &sa, 0, sizeof( sa ) ); // _bset
sa.sin_family = AF_INET;
// sa.sin_addr.s_addr = inet_addr( hb_parc( 3 ) );
sa.sin_addr.s_addr = htonl( INADDR_ANY );
wLen = recvfrom( hb_parni( 1 ), buffer, 8192, 0, ( struct sockaddr * ) &sa, &nLen );
if( wLen < 10000 && wLen > 0 )
hb_storclen( buffer, wLen, 2 );
else
hb_storclen( "", 0, 2 );
hb_storc( inet_ntoa( sa.sin_addr ), 3 );
hb_storni( htons( sa.sin_port ), 4 );
hb_retni( wLen );
free( buffer );
}
//---------------------------------------------------------------------------//
HB_FUNC( REMOTEPORT ) // nSocket
{
struct sockaddr_in sa;
int iLen = sizeof( sa );
memset( &sa, 0, sizeof( sa ) );
getpeername( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen );
hb_retni( ntohs( sa.sin_port ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( REMOTEIP ) // nSocket
{
struct sockaddr_in sa;
int iLen = sizeof( sa );
memset( &sa, 0, sizeof( sa ) );
getpeername( hb_parni( 1 ), ( struct sockaddr * ) &sa, &iLen );
hb_retc( inet_ntoa( sa.sin_addr ) );
}
//----------------------------------------------------------------------------//
HB_FUNC( BINDTOADDR ) // nSocket, nPort, cAddr
{
struct sockaddr_in sa; // sockaddr_in sa;
memset( &sa, 0, sizeof( sa ) );
sa.sin_family = AF_INET;
sa.sin_port = htons( hb_parni( 2 ) );
sa.sin_addr.s_addr = inet_addr( hb_parc( 3 ) );
hb_retl( bind( hb_parni( 1 ), ( struct sockaddr * ) &sa, sizeof( sa ) ) == 0 );
}
#pragma ENDDUMP