You are on page 1of 8

Socket Function Description Invoked By

socket() Creates a unique socket descriptor number Client & Server

setsockopt() Sets socket options Server

bind() Binds a socket to a particular IP address and port number Server

listen() Places a listener on the port specified by the bind function Server

accept() Accepts a connection request from another process Server

connect() Connects a client to the server endpoint specified in the socket address
structure Client

read() Reads data using the socket descriptor returned by the accept function
Client & Server

write() Writes data using the socket descriptor Client & Server

close() Closes the socket descriptor preventing further connection requests Client
& Server

Figure 1: Socket functions

Function Function Prototype in C

socket() int socket_descriptor = socket(int address_family, int type, int protocol)

setsockopt() int return_code = setsockopt(int socket_descriptor, int level, int


option_name, char *option_value, int option_length)

bind() int return_code = bind(int socket_descriptor, struct sockaddr


*local_address, int address_length)

connect() int return_code = connect(int socket_descriptor, struct sockaddr


*destination_address, int address_length)

listen() int return_code = listen(int socket_descriptor, int back_log)

accept() int return_code = accept(int socket_descriptor, struct sockaddr *address,


int *address_length)

read() int #of_bytes_read = read(int socket_descriptor, void *buffer, int


#of_bytes_to_read)

write() int #of_bytes_written = write(int socket_descriptor, const void* buffer,


#of_bytes_to_write)

Figure 2: Socket function prototypes in C

D Socket PR 10i 0 ExtProc('socket')

D AF_INET 10i 0 Value

D SOCK_STREAM 10i 0 Value

D UNUSED 10i 0 Value


D SetSockOpt PR 10i 0 ExtProc('setsockopt')

D SocketDId 10i 0 Value

D SOL_SOCKET 10i 0 Value

D SOL_REUSEADDR 10i 0 Value

D PtrToOn * Value

D SizeOfOn 10u 0 Value

D Bind PR 10i 0 ExtProc('bind')

D SocketDId 10i 0 Value

D PtrToSAddr * Value

D AddrLen 10u 0 Value

D Listen PR 10i 0 ExtProc('listen')

D SocketDId 10i 0 Value

D NbrOfClients 10i 0 Value

D Accept PR 10i 0 ExtProc('accept')

D SocketDId 10i 0 Value

D PtrToSAddr * Value

D PtrToAddrSz * Value

D Read PR 10i 0 ExtProc('read')

D SocketDId 10i 0 Value

D PtrToBuffer * Value

D SizeToRead 10i 0 Value

D Write PR 10i 0 ExtProc('write')

D SocketDId 10i 0 Value

D PtrToBuffer * Value

D SizeToRead 10i 0 Value

D Connect PR 10i 0 ExtProc('connect')

D SocketDId 10i 0 Value

D PtrToSAddr * Value

D SizeOfAddr 10u 0 Value

D Close PR 10i 0 ExtProc('close')


D SocketDId 10i 0 Value

D GetHostId PR 10u 0 ExtProc('gethostid')

D $$Errno PR * ExtProc('__errno')

D StrError PR * ExtProc('strerror')

D Errno 10i 0 Value

** C MACROS (CONSTANTS)

*D AF_INET C Const(2)

D SOCK_STREAM C Const(1)

D UNUSED C Const(0)

D SOL_SOCKET C Const(-1)

D SOL_REUSEADDR C Const(55)

* Error numbers from QSYSINC/SYS/ERRNO

* 3401 Permission denied.

D EACCES C Const(3401)

* 3422 The type of socket is not supported in this protocol family.

D EAFNOSUPPORT C Const(3422)

* complete code available on www.midrangecomputing.com

Figure 3: Socket function prototypes in RPG IV

/COPY QRPGLESRC,$SocketsH
* SOCKET ADDRESS STRUCTURE (TCP AND UDP)
D serveraddr DS
D sin_family 5i 0
D sin_port 5u 0
D sin_addr 10u 0
D sin_addrA 4a OVERLAY(sin_addr)
D sin_zero 8a
D Miscellaneous DS
D DspError 4S 0 INZ
D DspErrorA 4A OVERLAY(DspError)

* Miscellaneous Standalone fields.


D Message S 80a Based(pMessage)
D MsgToDsply S 52a INZ
D Errno S 10i 0 Based(perrno)
D Command S 80a INZ
D CommandLen S 15p 5 INZ(80)
D svaddrlen S 10u 0 INZ
D On S 10u 0 INZ(1)
D SDID S 10i 0 INZ
D SDID2 S 10i 0 INZ
D TotCharRead S 10i 0 INZ
D rc S 10i 0 INZ(0)
D SockError S 40A INZ('**Error on Socket create')
D SetSError S 40A INZ('**Error on Socket set')
D BindError S 40A INZ('**Error on binding to socket')
D ListenError S 40A INZ('**Error on listening')
D AcceptError S 40A INZ('**Error on accepting requests')
D Buffer S 10A INZ
D DataLen S 5P 0 INZ
D XLateTable S 10A INZ
D XLateTblLib S 10A INZ
* CONSTANTS A

D Dsplib C Const('DSPLIB LIB(')


D OutPut C Const(') OUTPUT(*PRINT)')
D BufferLen C Const(10)
* Create a socket descriptor for the server process to bind.
C EVAL SDID = Socket(AF_INET:SOCK_STREAM:UNUSED)
C IF (SDID < 0 )
C EVAL perrno = $$Errno
*

C SELECT
C WHEN Errno = EACCES
C Error3401 DSPLY

{ Do some special processing here}


C WHEN Errno = EAFNOSUPPORT
C Error3422 DSPLY

{ Do some special processing here}


C OTHER
C EVAL DspError = Errno
C EVAL pMessage = StrError(Errno)
C EVAL MsgToDsply = DspErrorA + ' ' + Message
C MsgToDsply DSPLY
C ENDSL
C SockError DSPLY
*

C EVAL *INLR = *ON


C RETURN
C ENDIF

*--------- Set socket descriptor to be reuseable.


C EVAL rc = SetSockOpt(SdId:SOL_SOCKET:
C SOL_REUSEADDR:%ADDR(On):%SIZE(On))
C IF (rc < 0 )
C EVAL perrno = $$Errno
C EVAL DspError = Errno
C EVAL pMessage = StrError(Errno)
C EVAL MsgToDsply = DspErrorA + ' ' + Message
C MsgToDsply DSPLY
C SetSError DSPLY
C EVAL *INLR = *ON
C RETURN
C ENDIF

*--------- Bind server IP & port to socket descriptor.


*

C EVAL sin_family = AF_INET


C EVAL sin_port = 3005

* replace X'be322607' with your as/400's ip or use gethostid function if client is


* on the same as400 as the server.
C******* OR EVAL sin_addrA = X'BE322607'
C EVAL sin_addr = GetHostId
C EVAL sin_zero = X'0000000000000000'
C EVAL svaddrlen = %SIZE(serveraddr)
C EVAL rc = Bind(SDID:%ADDR(serveraddr):
C svaddrlen)
C IF (rc < 0 )
C EVAL perrno = $$Errno
C EVAL DspError = Errno
C EVAL pMessage = StrError(Errno)
C EVAL MsgToDsply = DspErrorA + ' ' + Message
C MsgToDsply DSPLY
C BindError DSPLY
C EVAL *INLR = *ON
C RETURN
C ENDIF
*--------- willingness to accept connection requests.
C EVAL rc = Listen(SdId:10)

C IF (rc < 0 )
C EVAL perrno = $$Errno
C EVAL DspError = Errno
C EVAL pMessage = StrError(Errno)
C EVAL MsgToDsply = DspErrorA + ' ' + Message
C MsgToDsply DSPLY
C ListenError DSPLY
C EVAL *INLR = *ON
C RETURN
C ENDIF
*--------- Accept new connection requests. If rc is greater than zero,
*--------- the returned value is the socket descriptor identifier for
*--------- the client partner that requested the current connection.
C DOW ( Buffer <> '*STOPSVR' )
C EVAL rc = Accept(SDID:%ADDR(serveraddr):%ADDR(
C svaddrlen))
C IF ( rc < 0 )
C EVAL perrno = $$Errno
C EVAL DspError = Errno
C EVAL pMessage = StrError(Errno)
C EVAL MsgToDsply = DspErrorA + ' ' + Message
C MsgToDsply DSPLY
C AcceptError DSPLY
C EVAL *INLR = *ON
C RETURN
C ELSE
C EVAL SdId2 = rc
C ENDIF

C DOW ( rc > 0 )

*--------- Read from socket descriptor of accepted connection request


*--------- above.
C EVAL TotCharRead = *ZERO
C EVAL TotCharRead = Read(SdId2:%ADDR(Buffer):
C BufferLen)
*--------- Convert buffer data to EBCDIC to simulate source as a
*--------- PC client (ASCII Data).
C IF ( TotCharRead > *ZERO )
C CALL 'QDCXLATE' 68
C PARM BufferLen DataLen
C PARM Buffer
C PARM 'QEBCDIC' XLateTable
C PARM 'QSYS' XLateTblLib

C IF ( *IN68 = *OFF AND Buffer <> '*STOPSVR')


C EVAL Command = Dsplib + Buffer + OutPut
C CALL 'QCMDEXC' 68
C PARM Command
C PARM CommandLen
C ELSE
C Eval rc = Close(SdId2)
C LEAVE
C ENDIF

C ELSE
C Eval rc = Close(SdId2)
C LEAVE
C ENDIF
C ENDDO
C ENDDO

C Eval rc = Close(SdId)
C EVAL *INLR = *ON
C RETURN

N
H

Figure 4: Socket server source

C D

/COPY SYSINC,$SocketsH

C *Entry PList

C Parm Request

C EVAL Buffer = Request

*--------- Create a socket descriptor for the client process to

*--------- make a connection with.

C EVAL SdId = Socket(AF_INET:SOCK_STREAM:UNUSED)

C IF (SdId < 0 )

C EVAL perrno = $$Errno

C EVAL DspError = Errno

C EVAL pMessage = StrError(Errno)

C EVAL MsgToDsply = DspErrorA + ' ' + Message

C MsgToDsply DSPLY

C SockError DSPLY

C EVAL *INLR = *ON

C RETURN

C ENDIF

*--------- Connect to server process with client socket descriptor.

C EVAL sin_family = AF_INET

C EVAL sin_port = 3005

C EVAL sin_addrA = X'BE322607'

C EVAL sin_zero = X'0000000000000000'

C EVAL svaddrlen = %SIZE(serveraddr)


C EVAL rc = Connect(SdId:%ADDR(serveraddr):

C svaddrlen)

C IF (rc < 0 )

C EVAL perrno = $$Errno

C EVAL DspError = Errno

C EVAL pMessage = StrError(Errno)

C EVAL MsgToDsply = DspErrorA + ' ' + Message

C MsgToDsply DSPLY

C ConnectError DSPLY

C EVAL *INLR = *ON

C RETURN

C ENDIF

*--------- Convert buffer data to ASCII to simulate source as a

*--------- PC client. The server will convert it to EBCDIC before

*--------- executing DSPLIB OUTPUT(*PRINT) command.

C CALL 'QDCXLATE' 68

C PARM BufferLen DataLen

C PARM Buffer

C PARM 'QASCII' XLateTable

C PARM 'QSYS' XLateTblLib

*--------- Write library name to buffer.

C IF *IN68 = *OFF

C EVAL rc = Write(SdId:%ADDR(Buffer):BufferLen)

C ENDIF

*--------- Close the socket descriptor.

C Eval rc = Close(SdId)

C RETURN

You might also like