2010-06-08 21:54 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)

+ harbour/src/rtl/hbsockhb.c
    + added wrapper functions for Harbour socket API
      The list of exported functions is:
        HB_SOCKETGETERROR() --> nSocketError
        HB_SOCKETGETOSERROR() --> nOSError 
        HB_SOCKETERRORSTRING( [ nSocketErrror = hb_socketGetError() ] ) --> cError
        HB_SOCKETGETSOCKNAME( hSocket ) --> aAddr | NIL
        HB_SOCKETGETPEERNAME( hSocket ) --> aAddr | NIL
        HB_SOCKETOPEN( [ nDomain = HB_SOCKET_PF_INET ] , [ nType = HB_SOCKET_PT_STREAM ], [ nProtocol = 0 ] ) --> hSocket
        HB_SOCKETCLOSE( hSocket ) --> nSuccess
        HB_SOCKETSHUTDOWN( hSocket, [ nMode = HB_SOCKET_SHUT_RDWR ] ) --> nSuccess
        HB_SOCKETBIND( hSocket, aAddr ) --> nSuccess
        HB_SOCKETLISTEN( hSocket, [ iQueueLen = 10 ] ) --> nSuccess
        HB_SOCKETACCEPT( hSocket, [ @aAddr ], [ nTimeout = FOREVER ] ) --> nSuccess
        HB_SOCKETCONNECT( hSocket, aAddr, [ nTimeout = FOREVER ] ) --> nSuccess
        HB_SOCKETSEND( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesSent
        HB_SOCKETSENDTO( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], aAddr, [ nTimeout = FOREVER ] ) --> nBytesSent
        HB_SOCKETRECV( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesRecv
        HB_SOCKETRECVFROM( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], @aAddr, [ nTimeout = FOREVER ] ) --> nBytesRecv
        HB_SOCKETSETBLOCKINGIO( hSocket, lValue ) --> nSuccess
        HB_SOCKETSETNODELAY( hSocket, lValue ) --> nSuccess
        HB_SOCKETSETREUSEADDR( hSocket, lValue ) --> nSuccess
        HB_SOCKETSETKEEPALIVE( hSocket, lValue ) --> nSuccess
        HB_SOCKETSETBROADCAST( hSocket, lValue ) --> nSuccess
        HB_SOCKETSETSNDBUFSIZE( hSocket, nValue ) --> nSuccess
        HB_SOCKETSETRCVBUFSIZE( hSocket, nValue ) --> nSuccess
        HB_SOCKETGETSNDBUFSIZE( hSocket, @nValue ) --> nSuccess
        HB_SOCKETGETRCVBUFSIZE( hSocket, @nValue ) --> nSuccess
        HB_SOCKETSETMULTICAST( hSocket,  cAddr ) --> nSuccess
        HB_SOCKETSELECTREAD( hSocket,  [ nTimeout = FOREVER ] ) --> nRet
        HB_SOCKETSELECTWRITE( hSocket,  [ nTimeout = FOREVER ] ) --> nRet
        HB_SOCKETSELECTWRITEEX( hSocket,  [ nTimeout = FOREVER ] ) --> nRet
        HB_SOCKETSELECT( aRead, lSetRead, aWrite, lSetWrite, aExcep, lSetExcep, [ nTimeout = FOREVER ] ) --> nRet
        HB_SOCKETRESOLVEINETADDR( cAddr, nPort ) --> aAddr | NIL
        HB_SOCKETRESOLVEADDR( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> cResolved
        HB_SOCKETGETHOSTS( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> aHosts
        HB_SOCKETGETIFACES( [ nFamily ], [ lNoAliases ] ) --> aIfaces

  + harbour/examples/udpds
  + harbour/examples/udpds/udpds.prg
    + added UDP Discovery Server sample

      This module demonstrates a simple UDP Discovery Server
     
      If you run some service on the network (ex., netio), you need to
      know server IP address and configure client to connect to this
      address. UDPDS helps client to find server address (or addresses
      of multiple servers) on local network. UDPDS should be run in
      parallel to real server (ex., netio). Server part of UDPDS uses
      threads, so, it should be compiled in MT mode.
     
      Server functions:
        UDPDS_Start( nPort, cName [, cVersion ] ) --> hServer
        UDPDS_Stop( hServer ) 
        
      Client function:
        UDPDS_Find( nPort, cName ) --> { {"ip_addr_1", "version_1"}, ... }

    ; Please add .hbc, .hbp files, if it is required. This module requires 
      only a standard harbour runtime library and MT VM.
This commit is contained in:
Mindaugas Kavaliauskas
2010-06-08 18:54:58 +00:00
parent 45447a4c91
commit b9836e09ef
4 changed files with 862 additions and 2 deletions

View File

@@ -16,6 +16,68 @@
The license applies to all entries newer than 2009-04-28.
*/
2010-06-08 21:54 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
+ harbour/src/rtl/hbsockhb.c
+ added wrapper functions for Harbour socket API
The list of exported functions is:
HB_SOCKETGETERROR() --> nSocketError
HB_SOCKETGETOSERROR() --> nOSError
HB_SOCKETERRORSTRING( [ nSocketErrror = hb_socketGetError() ] ) --> cError
HB_SOCKETGETSOCKNAME( hSocket ) --> aAddr | NIL
HB_SOCKETGETPEERNAME( hSocket ) --> aAddr | NIL
HB_SOCKETOPEN( [ nDomain = HB_SOCKET_PF_INET ] , [ nType = HB_SOCKET_PT_STREAM ], [ nProtocol = 0 ] ) --> hSocket
HB_SOCKETCLOSE( hSocket ) --> nSuccess
HB_SOCKETSHUTDOWN( hSocket, [ nMode = HB_SOCKET_SHUT_RDWR ] ) --> nSuccess
HB_SOCKETBIND( hSocket, aAddr ) --> nSuccess
HB_SOCKETLISTEN( hSocket, [ iQueueLen = 10 ] ) --> nSuccess
HB_SOCKETACCEPT( hSocket, [ @aAddr ], [ nTimeout = FOREVER ] ) --> nSuccess
HB_SOCKETCONNECT( hSocket, aAddr, [ nTimeout = FOREVER ] ) --> nSuccess
HB_SOCKETSEND( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesSent
HB_SOCKETSENDTO( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], aAddr, [ nTimeout = FOREVER ] ) --> nBytesSent
HB_SOCKETRECV( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesRecv
HB_SOCKETRECVFROM( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], @aAddr, [ nTimeout = FOREVER ] ) --> nBytesRecv
HB_SOCKETSETBLOCKINGIO( hSocket, lValue ) --> nSuccess
HB_SOCKETSETNODELAY( hSocket, lValue ) --> nSuccess
HB_SOCKETSETREUSEADDR( hSocket, lValue ) --> nSuccess
HB_SOCKETSETKEEPALIVE( hSocket, lValue ) --> nSuccess
HB_SOCKETSETBROADCAST( hSocket, lValue ) --> nSuccess
HB_SOCKETSETSNDBUFSIZE( hSocket, nValue ) --> nSuccess
HB_SOCKETSETRCVBUFSIZE( hSocket, nValue ) --> nSuccess
HB_SOCKETGETSNDBUFSIZE( hSocket, @nValue ) --> nSuccess
HB_SOCKETGETRCVBUFSIZE( hSocket, @nValue ) --> nSuccess
HB_SOCKETSETMULTICAST( hSocket, cAddr ) --> nSuccess
HB_SOCKETSELECTREAD( hSocket, [ nTimeout = FOREVER ] ) --> nRet
HB_SOCKETSELECTWRITE( hSocket, [ nTimeout = FOREVER ] ) --> nRet
HB_SOCKETSELECTWRITEEX( hSocket, [ nTimeout = FOREVER ] ) --> nRet
HB_SOCKETSELECT( aRead, lSetRead, aWrite, lSetWrite, aExcep, lSetExcep, [ nTimeout = FOREVER ] ) --> nRet
HB_SOCKETRESOLVEINETADDR( cAddr, nPort ) --> aAddr | NIL
HB_SOCKETRESOLVEADDR( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> cResolved
HB_SOCKETGETHOSTS( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> aHosts
HB_SOCKETGETIFACES( [ nFamily ], [ lNoAliases ] ) --> aIfaces
+ harbour/examples/udpds
+ harbour/examples/udpds/udpds.prg
+ added UDP Discovery Server sample
This module demonstrates a simple UDP Discovery Server
If you run some service on the network (ex., netio), you need to
know server IP address and configure client to connect to this
address. UDPDS helps client to find server address (or addresses
of multiple servers) on local network. UDPDS should be run in
parallel to real server (ex., netio). Server part of UDPDS uses
threads, so, it should be compiled in MT mode.
Server functions:
UDPDS_Start( nPort, cName [, cVersion ] ) --> hServer
UDPDS_Stop( hServer )
Client function:
UDPDS_Find( nPort, cName ) --> { {"ip_addr_1", "version_1"}, ... }
; Please add .hbc, .hbp files, if it is required. This module requires
only a standard harbour runtime library and MT VM.
2010-06-08 20:28 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* src/rtl/hbregexc.c
+ Restored RTE which is thrown when unsupported regex string is
@@ -64794,7 +64856,7 @@
* harbour/contrib/gtwvg/wvgsink.c
* harbour/contrib/gtwvg/wvgax.c
! Fixes to newer OLE implementation.
Thanks to Mindaugus and Przemek for doing all the spadework.
Thanks to Mindaugas and Przemek for doing all the spadework.
Now I can receive events as was doing before, fantastic.
2009-05-18 21:36 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
@@ -82902,7 +82964,7 @@
* harbour/contrib/gtwvg/wvgsysw.prg
* harbour/contrib/gtwvg/wvgwnd.prg
! Fixed to respect new compiler warnings.
Thanks Mindaugus for this great addition.
Thanks Mindaugas for this great addition.
Hope code will be faster than before.
2008-12-20 18:35 UTC+0100 Francesco Saverio Giudice (info/at/fsgiudice.com)

View File

@@ -0,0 +1,125 @@
/*
* $Id$
*/
/*
* This module demonstrates a simple UDP Discovery Server
*
* If you run some service on the network (ex., netio) you need to
* know server IP address and configure client to connect to this
* address. UDPDS helps client to find server address (or addresses
* of multiple servers) on local network. UDPDS should be run in
* parallel to real server (ex., netio). Server part of UDPDS uses
* threads, so, it should be compiled in MT mode.
*
* Server functions:
* UDPDS_Start( nPort, cName [, cVersion ] ) --> hServer
* UDPDS_Stop( hServer )
*
* Client function:
* UDPDS_Find( nPort, cName ) --> { {"ip_addr_1", "version_1"}, ... }
*
*/
#include "hbsocket.ch"
/* Test application */
PROC main( cParam )
LOCAL h
IF ! HB_MTVM()
? "This sample should be compiled using MultiThread"
RETURN
ENDIF
IF cParam == NIL
? "udpds {c|s|cs}"
? "Parameter:"
? " s - run as a server"
? " c - run as a client"
RETURN
ENDIF
IF "S" $ UPPER( cParam )
IF ! EMPTY( h := UDPDS_Start( 39999, "UDPDSDemo", NETNAME() + " " + HB_TSTOSTR(HB_DATETIME() ) ) )
hb_idleSleep( 0.1 )
ENDIF
ENDIF
IF "C" $ UPPER( cParam )
? HB_VALTOEXP( UDPDS_Find( 39999, "UDPDSDemo" ) )
ENDIF
IF "S" $ UPPER( cParam )
? "Press any key to stop server"
INKEY(0)
UDPDS_Stop( h )
ENDIF
RETURN
/* Client */
FUNC UDPDS_Find( nPort, cName )
LOCAL hSocket, aRet, nEnd, nTime, cBuffer, nLen, aAddr
IF ! EMPTY( hSocket := hb_socketOpen( , HB_SOCKET_PT_DGRAM ) )
hb_socketSetBroadcast( hSocket, .T. )
IF hb_socketSendTo( hSocket, CHR( 5 ) + cName + CHR( 0 ),,, { HB_SOCKET_AF_INET, "255.255.255.255", nPort } ) == LEN( cName ) + 2
nTime := hb_milliseconds()
nEnd := nTime + 100 /* 100ms delay is enough on LAN */
aRet := {}
DO WHILE nEnd > nTime
cBuffer := SPACE( 2000 )
nLen := hb_socketRecvFrom( hSocket, @cBuffer,,, @aAddr, nEnd - nTime )
IF LEFT( cBuffer, LEN( cName ) + 2 ) == CHR( 6 ) + cName + CHR( 0 )
AADD( aRet, { aAddr[ 2 ], SUBSTR( cBuffer, LEN( cName ) + 3, nLen - LEN( cName ) - 2 ) } )
ENDIF
nTime := hb_milliseconds()
ENDDO
ENDIF
hb_socketClose( hSocket )
ENDIF
RETURN aRet
/* Server */
FUNC UDPDS_Start( nPort, cName, cVersion )
LOCAL hSocket
IF ! EMPTY( hSocket := hb_socketOpen( , HB_SOCKET_PT_DGRAM ) )
IF hb_socketBind( hSocket, { HB_SOCKET_AF_INET, "0.0.0.0", nPort } ) == 0
hb_threadDetach( hb_threadStart( @UDPDS(), hSocket, cName, cVersion ) )
RETURN hSocket
ENDIF
hb_socketClose( hSocket )
ENDIF
RETURN NIL
PROC UDPDS_Stop( hSocket )
hb_socketClose( hSocket )
RETURN
STATIC PROC UDPDS( hSocket, cName, cVersion )
LOCAL cBuffer, nLen, aAddr
DO WHILE .T.
cBuffer := SPACE( 2000 )
nLen := hb_socketRecvFrom( hSocket, @cBuffer,,, @aAddr )
IF nLen == -1
RETURN
ELSE
/*
* Communication protocol:
* Broadcast request: ENQ, ServerName, NUL
* Server response: ACK, ServerName, NUL, Version
*/
IF LEFT( cBuffer, nLen ) == CHR( 5 ) + cName + CHR( 0 )
hb_socketSendTo( hSocket, CHR( 6 ) + cName + CHR( 0 ) + IIF( cVersion == NIL, "", cVersion ),,, aAddr )
ENDIF
ENDIF
ENDDO
RETURN

View File

@@ -96,6 +96,7 @@ C_SOURCES := \
hbsha2.c \
hbsha2hm.c \
hbsocket.c \
hbsockhb.c \
hbstrfmt.c \
hbstrsh.c \
hbtoken.c \

672
harbour/src/rtl/hbsockhb.c Normal file
View File

@@ -0,0 +1,672 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* Socket API wrapper functions
*
* Copyright 2010 Mindaugas Kavaliauskas <dbtopas / at / dbtopas.lt>
* www - http://harbour-project.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
/*
* HB_SOCKETGETERROR() --> nSocketError
* HB_SOCKETGETOSERROR() --> nOSError
* HB_SOCKETERRORSTRING( [ nSocketErrror = hb_socketGetError() ] ) --> cError
* HB_SOCKETGETSOCKNAME( hSocket ) --> aAddr | NIL
* HB_SOCKETGETPEERNAME( hSocket ) --> aAddr | NIL
* HB_SOCKETOPEN( [ nDomain = HB_SOCKET_PF_INET ] , [ nType = HB_SOCKET_PT_STREAM ], [ nProtocol = 0 ] ) --> hSocket
* HB_SOCKETCLOSE( hSocket ) --> nSuccess
* HB_SOCKETSHUTDOWN( hSocket, [ nMode = HB_SOCKET_SHUT_RDWR ] ) --> nSuccess
* HB_SOCKETBIND( hSocket, aAddr ) --> nSuccess
* HB_SOCKETLISTEN( hSocket, [ iQueueLen = 10 ] ) --> nSuccess
* HB_SOCKETACCEPT( hSocket, [ @aAddr ], [ nTimeout = FOREVER ] ) --> nSuccess
* HB_SOCKETCONNECT( hSocket, aAddr, [ nTimeout = FOREVER ] ) --> nSuccess
* HB_SOCKETSEND( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesSent
* HB_SOCKETSENDTO( hSocket, cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], aAddr, [ nTimeout = FOREVER ] ) --> nBytesSent
* HB_SOCKETRECV( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], [ nTimeout = FOREVER ] ) --> nBytesRecv
* HB_SOCKETRECVFROM( hSocket, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nFlags = 0 ], @aAddr, [ nTimeout = FOREVER ] ) --> nBytesRecv
* HB_SOCKETSETBLOCKINGIO( hSocket, lValue ) --> nSuccess
* HB_SOCKETSETNODELAY( hSocket, lValue ) --> nSuccess
* HB_SOCKETSETREUSEADDR( hSocket, lValue ) --> nSuccess
* HB_SOCKETSETKEEPALIVE( hSocket, lValue ) --> nSuccess
* HB_SOCKETSETBROADCAST( hSocket, lValue ) --> nSuccess
* HB_SOCKETSETSNDBUFSIZE( hSocket, nValue ) --> nSuccess
* HB_SOCKETSETRCVBUFSIZE( hSocket, nValue ) --> nSuccess
* HB_SOCKETGETSNDBUFSIZE( hSocket, @nValue ) --> nSuccess
* HB_SOCKETGETRCVBUFSIZE( hSocket, @nValue ) --> nSuccess
* HB_SOCKETSETMULTICAST( hSocket, cAddr ) --> nSuccess
* HB_SOCKETSELECTREAD( hSocket, [ nTimeout = FOREVER ] ) --> nRet
* HB_SOCKETSELECTWRITE( hSocket, [ nTimeout = FOREVER ] ) --> nRet
* HB_SOCKETSELECTWRITEEX( hSocket, [ nTimeout = FOREVER ] ) --> nRet
* HB_SOCKETSELECT( aRead, lSetRead, aWrite, lSetWrite, aExcep, lSetExcep, [ nTimeout = FOREVER ] ) --> nRet
* HB_SOCKETRESOLVEINETADDR( cAddr, nPort ) --> aAddr | NIL
* HB_SOCKETRESOLVEADDR( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> cResolved
* HB_SOCKETGETHOSTS( cAddr, [ nFamily = HB_SOCKET_AF_INET ] ) --> aHosts
* HB_SOCKETGETIFACES( [ nFamily ], [ lNoAliases ] ) --> aIfaces
*/
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbvm.h"
#include "hbsocket.h"
HB_MAXINT hb_parnintdef( int iParam, HB_MAXINT iDefault )
{
return HB_ISNUM( iParam ) ? hb_parnint( iParam ) : iDefault;
}
typedef struct
{
HB_SOCKET socket;
} HB_PRG_SOCKET, * PHB_PRG_SOCKET;
static HB_BOOL s_fInit = HB_FALSE;
static HB_GARBAGE_FUNC( hb_socket_destructor )
{
PHB_PRG_SOCKET pSocket = ( PHB_PRG_SOCKET ) Cargo;
if( pSocket->socket != HB_NO_SOCKET )
{
hb_socketClose( pSocket->socket );
pSocket->socket = HB_NO_SOCKET;
}
}
static const HB_GC_FUNCS s_gcSocketFuncs =
{
hb_socket_destructor,
hb_gcDummyMark
};
static PHB_PRG_SOCKET socketParam( int iParam )
{
PHB_PRG_SOCKET pSocket = ( PHB_PRG_SOCKET ) hb_parptrGC( &s_gcSocketFuncs, iParam );
if( pSocket && pSocket->socket != HB_NO_SOCKET )
return pSocket;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return NULL;
}
static HB_BOOL socketaddrParam( int iParam, void ** pAddr, unsigned int * puiLen )
{
PHB_ITEM pItem = hb_param( iParam, HB_IT_ARRAY );
if( pItem && hb_socketAddrFromItem( pAddr, puiLen, pItem ) )
return HB_TRUE;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return HB_FALSE;
}
static void socket_exit( void * cargo )
{
HB_SYMBOL_UNUSED( cargo );
if( s_fInit )
{
hb_socketCleanup();
s_fInit = HB_FALSE;
}
}
static void socket_init( void )
{
if( ! s_fInit )
{
hb_socketInit();
hb_vmAtQuit( socket_exit, NULL );
s_fInit = HB_TRUE;
}
}
HB_FUNC( HB_SOCKETGETERROR )
{
hb_retni( hb_socketGetError() );
}
HB_FUNC( HB_SOCKETGETOSERROR )
{
hb_retni( hb_socketGetOsError() );
}
HB_FUNC( HB_SOCKETERRORSTRING )
{
if( HB_ISNUM( 1 ) )
hb_retc( hb_socketErrorStr( hb_parni( 1 ) ) );
else
hb_retc( hb_socketErrorStr( hb_socketGetError() ) );
}
HB_FUNC( HB_SOCKETGETSOCKNAME )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
void * addr;
unsigned int len;
if( hb_socketGetSockName( pSocket->socket, &addr, &len ) == 0 )
{
PHB_ITEM pItem = hb_socketAddrToItem( addr, len );
if( addr )
hb_xfree( addr );
if( pItem )
{
hb_itemReturnRelease( pItem );
return;
}
}
hb_ret();
}
}
HB_FUNC( HB_SOCKETGETPEERNAME )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
void * addr;
unsigned int len;
if( hb_socketGetPeerName( pSocket->socket, &addr, &len ) == 0 )
{
PHB_ITEM pItem = hb_socketAddrToItem( addr, len );
if( addr )
hb_xfree( addr );
if( pItem )
{
hb_itemReturnRelease( pItem );
return;
}
}
hb_ret();
}
}
HB_FUNC( HB_SOCKETOPEN )
{
HB_SOCKET socket;
int iDomain = hb_parnidef( 1, HB_SOCKET_PF_INET );
int iType = hb_parnidef( 2, HB_SOCKET_PT_STREAM );
int iProtocol = hb_parni( 3 );
socket_init();
if( ( socket = hb_socketOpen( iDomain, iType, iProtocol ) ) != HB_NO_SOCKET )
{
PHB_PRG_SOCKET pSocket = ( PHB_PRG_SOCKET ) hb_gcAllocate( sizeof( HB_PRG_SOCKET ),
&s_gcSocketFuncs );
pSocket->socket = socket;
hb_retptrGC( pSocket );
}
else
hb_retptr( NULL );
}
HB_FUNC( HB_SOCKETCLOSE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
int iRet = hb_socketClose( pSocket->socket );
pSocket->socket = HB_NO_SOCKET;
hb_retni( iRet );
}
}
HB_FUNC( HB_SOCKETSHUTDOWN )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketShutdown( pSocket->socket, hb_parnidef( 2, HB_SOCKET_SHUT_RDWR ) ) );
}
}
HB_FUNC( HB_SOCKETBIND )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
void * addr;
unsigned int len;
if( pSocket && socketaddrParam( 2, &addr, &len ) )
{
hb_retni( hb_socketBind( pSocket->socket, addr, len ) );
hb_xfree( addr );
}
}
HB_FUNC( HB_SOCKETLISTEN )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketListen( pSocket->socket, hb_parnidef( 2, 10 ) ) );
}
}
HB_FUNC( HB_SOCKETACCEPT )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
HB_SOCKET socket;
void * addr = NULL;
unsigned int len;
socket = hb_socketAccept( pSocket->socket, &addr, &len, hb_parnintdef( 3, -1 ) );
if( socket != HB_NO_SOCKET )
{
PHB_PRG_SOCKET pSocket = ( PHB_PRG_SOCKET ) hb_gcAllocate( sizeof( HB_PRG_SOCKET ),
&s_gcSocketFuncs );
pSocket->socket = socket;
hb_retptrGC( pSocket );
}
else
hb_retptr( NULL );
if( HB_ISBYREF( 2 ) )
{
PHB_ITEM pItem = hb_socketAddrToItem( addr, len );
if( pItem )
{
hb_itemParamStoreForward( 2, pItem );
hb_itemRelease( pItem );
}
else
hb_stor( 2 );
}
if( addr )
hb_xfree( addr );
}
}
HB_FUNC( HB_SOCKETCONNECT )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
void * addr;
unsigned int len;
if( pSocket && socketaddrParam( 2, &addr, &len ) )
{
hb_retni( hb_socketConnect( pSocket->socket, addr, len, hb_parnintdef( 3, -1 ) ) );
hb_xfree( addr );
}
}
HB_FUNC( HB_SOCKETSEND )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
long lLen = ( long ) hb_parclen( 2 );
if( HB_ISNUM( 3 ) )
{
long lParam = hb_parnl( 3 );
if( lParam >= 0 && lParam < lLen )
lLen = lParam;
}
hb_retnl( hb_socketSend( pSocket->socket, hb_parc( 2 ), lLen, hb_parni( 4 ),
hb_parnintdef( 5, -1 ) ) );
}
}
HB_FUNC( HB_SOCKETSENDTO )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
void * addr;
unsigned int len;
if( pSocket && socketaddrParam( 5, &addr, &len ) )
{
long lLen = ( long ) hb_parclen( 2 );
if( HB_ISNUM( 3 ) )
{
long lParam = hb_parnl( 3 );
if( lParam >= 0 && lParam < lLen )
lLen = lParam;
}
hb_retnl( hb_socketSendTo( pSocket->socket, hb_parc( 2 ), lLen, hb_parni( 4 ),
addr, len, hb_parnintdef( 6, -1 ) ) );
hb_xfree( addr );
}
}
HB_FUNC( HB_SOCKETRECV )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
PHB_ITEM pItem = hb_param( 2, HB_IT_STRING );
char * pBuffer;
HB_SIZE iLen;
if( pItem && HB_ISBYREF( 2 ) && hb_itemGetWriteCL( pItem, &pBuffer, &iLen ) )
{
if( HB_ISNUM( 3 ) )
{
long lRead = hb_parnl( 3 );
if( lRead >= 0 && lRead < ( long ) iLen )
iLen = lRead;
}
hb_retnl( hb_socketRecv( pSocket->socket, pBuffer, ( long ) iLen,
hb_parni( 4 ), hb_parnintdef( 5, -1 ) ) );
return;
}
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
}
HB_FUNC( HB_SOCKETRECVFROM )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
PHB_ITEM pItem = hb_param( 2, HB_IT_STRING );
char * pBuffer;
HB_SIZE iLen;
if( pItem && HB_ISBYREF( 2 ) && hb_itemGetWriteCL( pItem, &pBuffer, &iLen ) )
{
void * addr = NULL;
unsigned int len;
if( HB_ISNUM( 3 ) )
{
long lRead = hb_parnl( 3 );
if( lRead >= 0 && lRead < ( long ) iLen )
iLen = lRead;
}
hb_retnl( hb_socketRecvFrom( pSocket->socket, pBuffer, ( long ) iLen,
hb_parni( 4 ), &addr, &len,
hb_parnintdef( 6, -1 ) ) );
if( HB_ISBYREF( 5 ) )
{
PHB_ITEM pAddr = hb_socketAddrToItem( addr, len );
if( pAddr )
{
hb_itemParamStoreForward( 5, pAddr );
hb_itemRelease( pAddr );
}
else
hb_stor( 5 );
}
if( addr )
hb_xfree( addr );
return;
}
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
}
HB_FUNC( HB_SOCKETSETBLOCKINGIO )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetBlockingIO( pSocket->socket, hb_parl( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETNODELAY )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetNoDelay( pSocket->socket, hb_parl( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETREUSEADDR )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetReuseAddr( pSocket->socket, hb_parl( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETKEEPALIVE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetKeepAlive( pSocket->socket, hb_parl( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETBROADCAST )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetBroadcast( pSocket->socket, hb_parl( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETSNDBUFSIZE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetSndBufSize( pSocket->socket, hb_parni( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETSETRCVBUFSIZE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetRcvBufSize( pSocket->socket, hb_parni( 2 ) ) );
}
}
HB_FUNC( HB_SOCKETGETSNDBUFSIZE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
int size;
hb_retni( hb_socketGetSndBufSize( pSocket->socket, &size ) );
hb_storni( size, 2 );
}
}
HB_FUNC( HB_SOCKETGETRCVBUFSIZE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
int size;
hb_retni( hb_socketGetRcvBufSize( pSocket->socket, &size ) );
hb_storni( size, 2 );
}
}
HB_FUNC( HB_SOCKETSETMULTICAST )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSetMulticast( pSocket->socket, hb_parnidef( 2, HB_SOCKET_AF_INET ), hb_parc( 3 ) ) );
}
}
HB_FUNC( HB_SOCKETSELECTREAD )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSelectRead( pSocket->socket, hb_parnintdef( 2, -1 ) ) );
}
}
HB_FUNC( HB_SOCKETSELECTWRITE )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSelectWrite( pSocket->socket, hb_parnintdef( 2, -1 ) ) );
}
}
HB_FUNC( HB_SOCKETSELECTWRITEEX )
{
PHB_PRG_SOCKET pSocket = socketParam( 1 );
if( pSocket )
{
hb_retni( hb_socketSelectWriteEx( pSocket->socket, hb_parnintdef( 2, -1 ) ) );
}
}
static HB_SOCKET socketSelectCallback( PHB_ITEM pItem )
{
PHB_PRG_SOCKET pSocket = ( PHB_PRG_SOCKET ) hb_itemGetPtrGC( pItem, &s_gcSocketFuncs );
if( pSocket && pSocket->socket != HB_NO_SOCKET )
return pSocket->socket;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return HB_NO_SOCKET;
}
HB_FUNC( HB_SOCKETSELECT )
{
socket_init();
hb_retni( hb_socketSelect( hb_param( 1, HB_IT_ARRAY ), hb_parl( 2 ),
hb_param( 3, HB_IT_ARRAY ), hb_parl( 4 ),
hb_param( 5, HB_IT_ARRAY ), hb_parl( 6 ),
hb_parnintdef( 7, -1 ), socketSelectCallback ) );
}
HB_FUNC( HB_SOCKETRESOLVEINETADDR )
{
void * addr;
unsigned int len;
socket_init();
if( hb_socketResolveInetAddr( &addr, &len, hb_parc( 1 ), hb_parni( 2 ) ) )
{
PHB_ITEM pItem = hb_socketAddrToItem( addr, len );
if( addr )
hb_xfree( addr );
if( pItem )
{
hb_itemReturnRelease( pItem );
return;
}
}
hb_ret();
}
HB_FUNC( HB_SOCKETRESOLVEADDR )
{
char * szAddr;
socket_init();
szAddr = hb_socketResolveAddr( hb_parc( 1 ), hb_parnidef( 2, HB_SOCKET_AF_INET ) );
if( szAddr )
hb_retc_buffer( szAddr );
else
hb_retc( "" );
}
HB_FUNC( HB_SOCKETGETHOSTS )
{
PHB_ITEM pItem;
socket_init();
pItem = hb_socketGetHosts( hb_parc( 1 ), hb_parnidef( 2, HB_SOCKET_AF_INET ) );
if( pItem )
hb_itemReturnRelease( pItem );
else
hb_reta( 0 );
}
/*
This function is not implemented at C level, yet [Mindaugas]
HB_FUNC( HB_SOCKETGETALIASES )
{
PHB_ITEM pItem;
socket_init();
pItem = hb_socketGetAliases( hb_parc( 1 ), hb_parnidef( 2, HB_SOCKET_AF_INET ) );
if( pItem )
hb_itemReturnRelease( pItem );
else
hb_reta( 0 );
}
*/
HB_FUNC( HB_SOCKETGETIFACES )
{
PHB_ITEM pItem;
socket_init();
pItem = hb_socketGetIFaces( hb_parni( 1 ), hb_parl( 2 ) );
if( pItem )
hb_itemReturnRelease( pItem );
else
hb_reta( 0 );
}