|
This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. -- For some reason the attachment got stripped off. Let's see if it goes this time. Tom ps - I've since taken Scott's suggestion to handle the return code on the select() - unforunately to no affect. Still looking at it.... | -----Original Message----- | From: PatrickConner@parkdalemills.com | [mailto:PatrickConner@parkdalemills.com] | Sent: Friday, December 21, 2001 15:48 | To: rpg400-l@midrange.com | Subject: RE: socket problem | | | | Did the code come through? I never saw it. | | Patrick Conner | www.ConnecTown.com | (828) 244-0822 -- D*===================================================================================================== D* Definitions relating to the select() function. Includes the typedef for fd_set and the macros D* needed to manipulate variables of type fd_set. D* D* fd_set is a minimum of 7 integers (up to 224 bits) for compatibility with previous releases. D* It may be larger, depending on the value of FD_SETSIZE. D* D* from: QSYSINC/SYS.TYPES D* D* #ifndef FD_SETSIZE D* #define FD_SETSIZE 200 /* Maximum descriptors in set */ D* #endif D* D* typedef struct fd_set{ D* unsigned int fdes[((FD_SETSIZE) <= 224) ? (7) : D* ((((FD_SETSIZE)-1)/(8*sizeof(int)))+1)]; D* } fd_set; D* D* D* This is the RPG equivalent for FDSET structure: D* D*FDSET DS D* fdes 10U 0 DIM(7) D* D* To use the procedures you will need to pass a pointer to a structure of this type. D* D*--------------- D* prototypes for RPG procedures duplicating fd_set C macros D D FD_ZERO PR D p_FDSET * value D D FD_SET PR D FD 10i 0 D p_FDSET * value D D FD_CLR PR D FD 10i 0 D p_FDSET * value D D FD_ISSET PR 1 D FD 10i 0 D p_FDSET * value D D* define an fdset structure DFDSET DS D fdes 10U 0 DIM(7) D DpFDSET S * INZ(%addr(FDSET)) D D*===================================================================================================== D* prototypes for bit manipulation procedures. these are used by the FD_SET macros D* D* ---- D* logical NOT a byte D $NOT PR 1 D byte 1 value D* D* ---- D* logical AND two bytes D $AND PR 1 D byte1 1 value D byte2 1 value D* D* ---- D* logical OR two bytes D $OR PR 1 D byte1 1 value D byte2 1 value D* D* ---- D* logical NOT a 4 byte binary fields D #NOT PR 10U 0 D int 10U 0 value D* D* ---- D* logical AND two 4 byte binary fields D #AND PR 10U 0 D int1 10U 0 value D int2 10U 0 value D* D* ---- D* logical OR two 4 byte binary fields D #OR PR 10U 0 D int1 10U 0 value D int2 10U 0 value D* D* ---- D* Shift bits left 4 byte binary field D #ShiftLeft PR 10U 0 D int 10U 0 value D NumBits2Shift 10U 0 value D* D* ---- D* Shift bits right 4 byte binary field D #ShiftRight PR 10U 0 D int 10U 0 value D NumBits2Shift 10U 0 value DMI_Time PR ExtProc('mitime') D p_MI_TimeVal * Value D MITimeValHours 10i 0 Value hours D MITimeValMins 10i 0 Value minutes D MITimeValSecs 10i 0 Value seconds D MITimeValHsec 10i 0 Value 100's of a second D* D* D MI_TimeVal S 8 D* D p_MI_TimeVal S * D* D MITimeValHours S 10i 0 hours D MITimeValMins S 10i 0 minutes D MITimeValSecs S 10i 0 seconds D MITimeValHsec S 10i 0 100's of a second D* D*===================================================================================================== D* D* Buffers for reading and writing to the socket D* D* ---- D* Output buffer D* D BufferOut S 1034A D pBufferOut S * INZ(%ADDR(BufferOut)) D* D BufferOutSz S 10I 0 INZ(%Len(BufferOut)) D* D* ---- D* Input buffer D* D BufferIn S 3072a D pBufferIn S * INZ(%ADDR(BufferIn)) D* D BufferInSz S 10I 0 INZ(%Len(BufferIn)) D* D* ---- D* Work buffer D* D WorkBuffer S 3072a D pWorkBuffer S * INZ(%ADDR(WorkBuffer)) D* D WorkBufferSz S 10I 0 INZ(%Len(WorkBuffer)) D*===================================================================================================== D* . . . C* ---- C* Retreive SMDR C DoW 0 = 0 DO FOREVER C* C* - Check for TCM Collector Start/Stop or ProgramEnd request C Eval RC = ProgramControl C If RC < 0 end the pgm C Leave C EndIf C* C MOVEL *ALLx'00' GET10 8 C EVAL Get10 = x'534E523A31300D0A' ascii: 'SNR:10' + CRLF C MOVEL Get10 BufferOut C EVAL RC = Write( SdId C : pBufferOut C : 8 C ) C* C* - Read 'n' number of RECORDS from socket C Do 5 C Eval RC = ReadSocketRec( SdId socket descriptor C : pBufferIn point to BufferIn C : 3000 max chars C ) C If RC > 0 C Leave C EndIf C EndDo C C If RC = 0 tried 5 times & still nothing C Leave C EndIf C* - translate to EBCDIC C CALL 'QDCXLATE' 68 C PARM 3000 DataLen C PARM BufferIn C PARM 'QTCPEBC' XLateTable C PARM 'QUSRSYS' XLateTblLib C* C* place a sentinal to mark the end of the received data C X'0D0000' SCAN BufferIn X 99 C 99 EVAL %SUBST( BufferIn : X : 1) = '~' C N99 MOVE '~' BufferIn C* C* - extract and process each record from the returned data - records are delimted by the tilde C* C Z-ADD 1 I 5 0 C* C DOW I < 3000 C '~' SCAN BufferIn:I Z 5 0 99 C N99 LEAVE C EVAL TDATA = %SUBST(BufferIn : I : Z - I) C* C IF %SUBST(TDATA : 1 : 40) <= *BLANKS C OR C %SUBST(TDATA : 1 : 2) = 'OK' C EVAL I = Z + 1 C ITER C ENDIF C* C* - Write data to DATA QUEUE and 'PBXDUMP' C* C* date/time stamp C TIME TIMESTAMP 12 0 C MOVE TIMESTAMP TDATA 150 C* C IF TNDBOK = 'Y' C EVAL pRIOFB = Rwrite( pFile C : %addr(TDATA) C : 150 C ) C ENDIF C* C IF TNDQOK = 'Y' C* C MOVEL TNDQNM QNAME C MOVEL TNDQLB QLIB C Z-ADD 150 QLEN C* C CALL 'QSNDDTAQ' C PARM QNAME 10 C PARM QLIB 10 C PARM QLEN 5 0 C PARM TDATA C* C ENDIF C* C EVAL I = Z + 1 C ENDDO C C EndDo DO FOREVER C* C*===================================================================================================== PReadSocketRec B D ReadSocketRec Pr 10i 0 D SD 10I 0 Value D SockData@ * Value D MaxDataLen 10I 0 Value D ReadSocketRec PI 10i 0 D SD 10I 0 Value D SockData@ * Value D MaxDataLen 10I 0 Value D DataLeft S 10I 0 D TotChars S 10i 0 Inz(0) # of chars received thus far D CharsRead S 10I 0 Inz(0) # of chars on this read() D RC S 10I 0 C* Clear buffers and initialize fields C Eval WorkBuffer = *allx'00' C Eval BufferIn = *allx'00' C Eval CharsRead = 0 C Eval TotChars = 0 C Eval DataLeft = MaxDataLen C* C* read until MaxDataLen chars have been received or end of record char encountered C DoW TotChars < MaxDataLen C* C**** Eval CharsRead = ReadSocket( SD used for non blocking reads C**** : pWorkBuffer C**** : DataLeft C**** : 5 C**** ) C Z-ADD 3 TimeValSec C Z-ADD *zeros TimeValMsec C Do 5 C CALLP FD_ZERO(pFDSET) C CALLP FD_SET(SD : pFDSET) C EVAL RC = Select( SD + 1 C : pFDSET read set C : *NULL write set C : *NULL error set C : %addr(TimeVal) C ) C EVAL *IN99 = FD_ISSET(SD : pFDSET) C If *IN99 = *ON C Eval CharsRead = Read( SD used for blocking reads C : pWorkBuffer C : DataLeft C ) C Leave C Else C Iter timed out, retry C EndIf C EndDo C If CharsRead < 0 C Eval ErrNo@ = GetErrNo C Eval ErrMsg@ = StrError(ErrNo) C leave C EndIf C C* move the data from the work buffer to the input buffer we're building C Eval %Subst(BufferIn : TotChars + 1 : CharsRead) C = %Subst(WorkBuffer : 1 : CharsRead) C* C* Increase the number of bytes received thus far C Eval TotChars = TotChars + CharsRead C* C* Decrease the number of bytes needed to reach MaxDataLen C Eval DataLeft = DataLeft - CharsRead C* C* check if EOR has been read yet C x'0D00' SCAN BufferIn 99 remember: ASCII C 99 LEAVE C* C EndDo C* C Return TotChars C* PReadSocketRec E C*===================================================================================================== P FD_ZERO B D* zero out an FDSET D PI D p_FDSET * value * * set all 0 * * #define FD_ZERO(fds) (memset(fds,0,sizeof(fd_set))) * DFDSET DS BASED(p_FDSET) D fdes 10U 0 DIM(7) C Z-ADD *ZEROS FDES P FD_ZERO E *------------ P FD_SET B D* add an SD to an FDSET D PI D FD 10i 0 D p_FDSET * value * * set bits * * #define FD_SET(fd, fds) \ * ((fds)->fdes[(fd)/32] |= (1 << ((fd)%32))) * D index S 10U 0 DFDSET DS BASED(p_FDSET) D fdes 10U 0 DIM(7) C EVAL index = ( %DIV(FD : 32) + 1 ) C EVAL fdes(index) = C #OR( C fdes(index) : C #ShiftLeft(1 : %rem(FD : 32) ) C ) P FD_SET E *------------ P FD_CLR B D* clear an SD from an FDSET D PI D FD 10i 0 D p_FDSET * value * * clear bits * * #define FD_CLR(fd, fds) \ * ((fds)->fdes[(fd)/32] &= ~(1 << ((fd)%32))) * D index S 10U 0 DFDSET DS BASED(p_FDSET) D fdes 10U 0 DIM(7) C EVAL index = ( %DIV(FD : 32) + 1 ) C EVAL fdes( index ) = C #AND( C fdes(index) : C #NOT( C #ShiftLeft(1 : %rem(fd : 32) ) C ) C ) P FD_CLR E *------------ P FD_ISSET B D* check if an SD is in an FDSET D PI 1 D FD 10i 0 D p_FDSET * value * * check bits * * #define FD_ISSET(fd, fds) \ * (((fds)->fdes[(fd)/32] & (1 << ((fd)%32)))? 1 : 0) * D RETVAL S 1 D index S 10U 0 D integer S 10U 0 DFDSET DS BASED(p_FDSET) D fdes 10U 0 DIM(7) * C EVAL RETVAL = *OFF C EVAL index = ( %DIV(FD : 32) + 1 ) C EVAL integer = C #AND( C fdes( index ) : C #ShiftLeft(1 : %rem(fd : 32) ) C ) C IF INTEGER > *ZERO C EVAL RETVAL = *ON C ENDIF C RETURN RETVAL * P FD_ISSET E *------------ *========================================================================= P $AND B D* bitwise AND two bytes D PI 1 D byte_in1 1 value D byte_in2 1 value D ReturnValue S 1 C BitOn x'FF' ReturnValue C Eval byte_in1 = $NOT(byte_in1) C Eval byte_in2 = $NOT(byte_in2) C BitOff byte_in1 ReturnValue C BitOff byte_in2 ReturnValue C Return ReturnValue P $AND E *------------ P $OR B D* bitwise OR two bytes D PI 1 D byte_in1 1 value D byte_in2 1 value D ReturnValue S 1 C BitOff x'FF' ReturnValue C BitOn byte_in1 ReturnValue C BitOn byte_in2 ReturnValue C Return ReturnValue P $OR E *------------ P $NOT B D* bitwise NOT a single byte D PI 1 D byte_in 1 value D ReturnValue S 1 C BitOn x'FF' ReturnValue C BitOff byte_in ReturnValue C Return ReturnValue P $NOT E *------------ P #AND B D* bitwise AND two integers D PI 10U 0 D int_in1 10U 0 value D int_in2 10U 0 value D index S 10U 0 D DS D integer1 10U 0 D ar1 1 Dim(4) overlay(integer1) D integer2 10U 0 D ar2 1 Dim(4) overlay(integer2) D result 10U 0 D ar3 1 Dim(4) overlay(result) D ReturnValue S 10U 0 C Eval integer1 = int_in1 C Eval integer2 = int_in2 C Do 4 INDEX C Eval ar3(INDEX) = $AND(AR1(INDEX):AR2(INDEX)) C EndDo C Eval ReturnValue = result C Return ReturnValue P #AND E *------------ P #OR B D* bitwise OR two integers D PI 10U 0 D int_in1 10U 0 value D int_in2 10U 0 value D index S 10U 0 D DS D integer1 10U 0 D ar1 1 Dim(4) overlay(integer1) D integer2 10U 0 D ar2 1 Dim(4) overlay(integer2) D result 10U 0 D ar3 1 Dim(4) overlay(result) D ReturnValue S 10U 0 C Eval integer1 = int_in1 C Eval integer2 = int_in2 C Do 4 INDEX C Eval ar3(INDEX) = $OR(AR1(INDEX):AR2(INDEX)) C EndDo C Eval ReturnValue = result C Return ReturnValue P #OR E *------------ P #NOT B D* bitwise NOT an integer D PI 10U 0 D int_in1 10U 0 value D index S 10U 0 D DS D integer1 10U 0 D ar1 1 Dim(4) overlay(integer1) D result 10U 0 D ar2 1 Dim(4) overlay(result) D ReturnValue S 10U 0 C Eval integer1 = int_in1 C Do 4 INDEX C Eval ar2(INDEX) = $NOT(AR1(INDEX)) C EndDo C Eval ReturnValue = result C Return ReturnValue P #NOT E *------------ P #ShiftLeft B D* bitwise shift left D PI 10U 0 D int_in 10U 0 value D BitsToShift 10U 0 value D index S 10U 0 D DS D result 10U 0 D ar1 1 Dim(4) overlay(result) D ReturnValue S 10U 0 C Eval result = int_in C Do BitsToShift INDEX C BitOff '0' ar1(1) C Eval Result = Result * 2 C EndDo C Eval ReturnValue = result C Return ReturnValue P #ShiftLeft E *------------ P #ShiftRight B D* bitwise shift right D PI 10U 0 D int_in 10U 0 value D BitsToShift 10U 0 value D index S 10U 0 D DS D result 10U 0 D ar1 1 Dim(4) overlay(result) D ReturnValue S 10U 0 C Eval result = int_in C Do BitsToShift INDEX C BitOff '7' ar1(4) C Eval Result = Result / 2 C EndDo C Eval ReturnValue = result C Return ReturnValue P #ShiftRight E *------------ C*=====================================================================================================
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.