550 likes | 708 Views
Socket Programming. Edsel Garcia Principal Technical Support Engineer. How Do Applications Talk?. Web. 4GL. Sockets & Protocols. X App. Java. Why Sockets in the 4GL?. Stock Market. Web Server. Mail Server. 4GL. Java. 4GL. Agenda. TCP/IP and socket basics
E N D
Socket Programming Edsel Garcia Principal Technical Support Engineer
How Do Applications Talk? Web 4GL Sockets & Protocols X App Java
Why Sockets in the 4GL? Stock Market Web Server Mail Server 4GL Java 4GL
Agenda • TCP/IP and socket basics • Application protocol design • 4GL sockets
Clients and Servers • The terms “client” and “server” are in the eye of the beholder • The Server provides some service • It waits for connections • It must be started first • It does not know who will connect or when • The Client connects to a running server • It knows who it is connecting to • Both agree on how to exchange data
Protocol Layers Application Transport Network Datalink Telnet HTTP Your App TCP UDP IP Ethernet
Transmission Control Protocol (TCP) • A transport layer protocol • Connection-oriented • Point-to-point • Byte stream • Looks like reading and writing files • You must design the messages • Reliable • But not guaranteed • Usually called “TCP/IP”
Sockets • A TCP socket is one end of a virtual communication link connecting two programs • A client and a server • Once a socket is created and a connection established, you just read and write data
TCP Addressing TCP TCP IP 172.18.103.49 IP 172.18.103.48 Ethernet Ethernet Host herta Host zeus Application 1 Application 2 Port 3028 Port 5124
Servers • Listens for connection requests on a specified port • A well-known port • A registered or ephemeral port • Accept connection requests and get a socket for each connection • Read and write data as required • Close the connections • Delete the sockets
Clients • Create a socket • Connect to a server on a specified host and port – client port is usually dynamically assigned • Read and write data as necessary • Disconnect from the server • Delete socket
TCP/IP References • http://www.faqs.org/rfcs • Complete set of IETF RFC documents • UNIX Network ProgrammingW. Richard StevensISBN 0-13-490012-X • Excellent book (mostly) on TCP/IP • Uses C, but very complete • http://www.private.org.il/tcpip_rl.html • A huge annotated list of TCP/IP resources • Books, web sites, papers, etc.
Protocol • A set of rules that define how we should behave • Data communication protocols are very formal and precise • If you break the rules, you can’t communicate • Use messages
Most protocols use more than one kind of message Each kind of message is identified by a message type of some kind Types are typically identified by An integer type code Login = 1, logout = 2, get time = 3, etc. A sequence of characters “GET”, “POST”, etc. Message Types
Field layouts Message and field size Numeric byte-order Character encoding Message Formats
Example Message Layout version length csnetheader seq-num csmssgheader version hdl type Optional data
Field Layout Type = connect length username length password length info
Numeric Byte Ordering Low-orderbyte High-orderbyte High-orderbyte Low-orderbyte little-endian 07 00 address a address a+1 big-endian 00 07 address a address a + 1 0x0007 does not equal 0x0700
Character Encoding • ASCII • EBCDIC • Unicode • UTF-8 • ISO8859-1 • ISO8859-8
4GL Sockets • Connecting a client to a server • Accepting connections on a server • Reading and writing data on a socket • Marshalling and unmarshalling data
Connecting a Client to a Server • CREATE SOCKET handle • handle:CONNECT(connection-params-string) • connection-params-string • -H - Host or IP Address to connect to • -S - port to connect to - a number or service • handle:DISCONNECT()
Connecting a Client to a Server DEFINE VARIABLE sckt-hndl AS HANDLE. DEFINE VARIABLE ret AS LOGICAL. CREATE SOCKET sckt-hndl. ret = sckt-hndl:CONNECT ("-H acura -S 80"). /* Do fun stuff with the socket */ ret = sckt-hndl:DISCONNECT ().
Accepting Connections on a Server • SERVER-SOCKET object • ENABLE-CONNECTIONS(connection-params-string) method • Use –S parameter to specify the port to listen on
Accepting Connections on a Server • CONNECT event on SERVER-SOCKET object accepts connections • SET-CONNECT-PROCEDURE(internal-proc) method to process new connections • Input parameter to connect event procedure is the new socket
Accepting Connections on a Server CREATE SERVER-SOCKET sckt-hndl NO-ERROR. log = sckt-hndl:ENABLE-CONNECTIONS("-S 5555"). sckt-hndl:SET-CONNECT-PROCEDURE ("connHandler",THIS-PROCEDURE). WAIT-FOR CLOSE OF THIS-PROCEDURE. PROCEDURE connHandler. /* Handle Connect Events */ DEFINE INPUT PARAMETER connect-sckt AS HANDLE. /* Do fun stuff with connect-sckt */ END PROCEDURE.
Using MEMPTRs READ() method WRITE () method Supporting the I/O models Reading and Writing Data on a Socket
Using Memptrs • Define a MEMPTR variable • Allocate a region of memory using SET-SIZE(ptr) = n • Read and write to specified locations within the MEMPTR • Free the memory using SET-SIZE(ptr)=0
Read/Writing a Memptr Numeric Datatypes • PUT-datatype ( memptr , byte-position ) = expression • GET-datatype ( memptr , byte-position )
Read/Writing a Memptr Setting Byte Order • SET-BYTE-ORDER( memptr ) = int-expression • BIG-ENDIAN • LITTLE-ENDIAN
Reading/Writing a Memptr Strings • Either NULL terminated or based on number of bytes specified • You need to convert to the correct code page with CODEPAGE-CONVERT() function PUT-STRING ( memptr, position [ , numbytes ] ) = expression String = GET-STRING ( memptr, position [ , numbytes ] )
Reading/Writing a Memptr A few others • PUT-BYTES, GET-BYTES • moves RAW and MEMPTRs • PUT-BITS, GET-BITS • manipulates bits within INTEGERs
Writing to a Socket • WRITE(memptr, position, bytes-to-write ) • Only means that the data has been written • No guarantee that the other endpoint received it or understood it
Example Message Example Message 4 4 LEN ID LEN NAME Total Length = 8 + Len
Example - Writing to a Socket DEFINE VARIABLE hSocket AS HANDLE. DEFINE VARIABLE mBuffer AS MEMPTR. DEFINE VARIABLE id AS INTEGER INITIAL 543. DEFINE VARIABLE len as INTEGER. DEFINE VARIABLE name AS CHAR. name = ”YourNameHere". len = LENGTH(name, “RAW”). SET-SIZE(mBuffer) = len + 8. SET-BYTE-ORDER(mBuffer) = BIG-ENDIAN. PUT-LONG(mbuffer,1) = id. PUT-LONG(mbuffer,5) = len. PUT-STRING(mBuffer,9,len) = name. hSocket:WRITE(mBuffer,1,GET-SIZE(mBuffer)).
Reading from a Socket • READ(memptr, position, bytes-to-read [,mode] ) • Read is blocking - You will get a least 1 byte or an error • How many bytes read depends on the mode and the number specified • Read Available • Read Exactly
Example - Reading from a Socket DEFINE VARIABLE hSocket AS HANDLE. DEFINE VARIABLE mBuffer AS MEMPTR. DEFINE VARIABLE id AS INTEGER. DEFINE VARIABLE len AS INTEGER. DEFINE VARIABLE name AS CHAR. SET-SIZE(mBuffer) = 8. SET-BYTE-ORDER(mBuffer) = BIG-ENDIAN. hSocket:READ(mBuffer,1,8). id = GET-LONG(mBuffer, 1). len = GET-LONG(mBuffer,5). SET-SIZE(mBuffer) = 0. SET-SIZE(mBuffer) = len. hSocket:READ(mBuffer,1,len). name = GET-STRING(mBuffer,1,len).
Supporting Different I/O Models Blocking • Use the Read() method SET-SIZE(mBuffer) = 4. SET-BYTE-ORDER(mBuffer) = BIG-ENDIAN. hSocket:READ(mBuffer,1,4). Len = GET-LONG(mBuffer,1). SET-SIZE(mBuffer) = 0. SET-SIZE(mBuffer) = len. hSocket:READ(mBuffer,1,len).
Supporting Different I/O Models Non-Blocking • Use the CONNECTED() method to check for valid connection • Use the BYTES-AVAILABLE() method to check if bytes are available and how many • Use the READ() method to read the data that is available
Non-blocking Read() SET-SIZE(mptr) = msgsize. got = 0. REPEAT WHILE got < msgsize: IF NOT hSocket:CONNECTED() THEN LEAVE. len = hSocket:GET-BYTES-AVAILABLE(). IF len > 0 THEN do: hSocket:READ(mptr, got + 1, len). got = got + len. END. ELSE do: /* something while waiting */ end. END. rsp = GET-STRING(mptr,2,got - 2).
Supporting Different I/O Models Event-Driven • READ-RESPONSE event on a SOCKET object • SET-READ-RESPONSE-PROCEDURE (internal-proc) - method to set event procedure • Use SELF to reference SOCKET object
Event-Driven Input for a Client Data SELF:Read() Wait-for Read-Response- Procedure
Event-Driven Client CREATE SOCKET sckt-hndl. ret = sckt-hndl:CONNECT ("-H acura -S 80"). ret = sckt-hndl:SET-READ-RESPONSE-PROCEDURE ("readHandler", THIS-PROCEDURE). REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE: /* … leave condition */ WAIT-FOR READ-RESPONSE OF sckt-hndl. END. PROCEDURE readHandler. /* read-response event */ SELF:READ(mem1,...). END PROCEDURE.
Event-Driven Input for a Server Connect hdl:set-read-procedure() Data SELF:Read() Wait-for Connect Procedure Read-Response- Procedure
Event-Driven Server CREATE SERVER-SOCKET sckt-hndl NO-ERROR. log = sckt-hndl:ENABLE-CONNECTIONS("-S 5555"). sckt-hndl:SET-CONNECT-PROCEDURE ("connectHandler",THIS-PROCEDURE). WAIT-FOR U1 OF THIS-PROCEDURE. PROCEDURE connectHandler. /* Connect Event */ DEFINE INPUT PARAMETER read-sckt AS HANDLE. read-sckt:SET-READ-RESPONSE-PROCEDURE ("readHandler",THIS-PROCEDURE). END PROCEDURE.
Event-Driven Server (cont) PROCEDURE readHandler. /* read-response event */ SET-SIZE(mBuffer) = 8. SET-BYTE-ORDER(mBuffer) = BIG-ENDIAN. hSocket:READ(mBuffer,1,8). id = GET-LONG(mBuffer, 1). len = GET-LONG(mBuffer,5). SET-SIZE(mBuffer) = 0. SET-SIZE(mBuffer) = len. hSocket:READ(mBuffer,1,len). name = GET-STRING(mBuffer,1,len). END PROCEDURE.