Socket programming with Java - can't send data to Java

Hi -

I'm trying to use sockets to communicate between Progress and a Java class. The Progress code is definitely connecting the class, but sending data isn't working. Can someone point me in the right direction? The code below has a couple of comments to explain where I see the code working and not working.

Thank you for any advice and time that you can provide.

I attached the Java and Progress code in addition to pasting it below.

Progress code:
Code:
DEFINE VARIABLE hSocket             AS HANDLE NO-UNDO.
DEFINE VARIABLE lRC                 AS LOGICAL NO-UNDO.
DEFINE VARIABLE mHeader             AS MEMPTR NO-UNDO.
DEFINE VARIABLE mData               AS MEMPTR NO-UNDO.
DEFINE VARIABLE iDataSize           AS INTEGER NO-UNDO.
DEFINE VARIABLE cText               AS CHARACTER NO-UNDO.
define variable cString             as char.
PAUSE 0 BEFORE-HIDE.

CREATE SOCKET hSocket.

hSocket:CONNECT('-H localhost -S 9898') NO-ERROR.   /* was 55428 */
IF hSocket:CONNECTED() = FALSE THEN DO:
  MESSAGE 'Unable to connect' view-as alert-box.
  return.

END.
ELSE DO:
  /* This works just fine */
    MESSAGE "I am connected" VIEW-AS ALERT-BOX.

END.

SET-SIZE(mHeader) = 4.
SET-BYTE-ORDER(mHeader) = BIG-ENDIAN.

/* I don't see that readProc ever gets executed */
hSocket:SET-READ-RESPONSE-PROCEDURE('readProc').

REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:
  IF hSocket:CONNECTED() THEN DO:
    UPDATE cText.
    ASSIGN iDataSize = LENGTH(cText).
    SET-SIZE(mData) = iDataSize.
    SET-BYTE-ORDER(mData) = BIG-ENDIAN.
    PUT-STRING(mData, 1, iDataSize) = cText.
   
    MESSAGE "writing?" GET-SIZE(mData) VIEW-AS ALERT-BOX.
    hSocket:WRITE(mData, 1, GET-SIZE(mData)).
   
    WAIT-FOR READ-RESPONSE OF hSocket.
 
  END.
  ELSE DO:
    LEAVE.
  END.

END.

hSocket:DISCONNECT() NO-ERROR.
DELETE OBJECT hSocket.
SET-SIZE(mHeader) = 0.
SET-SIZE(mData) = 0.
QUIT.


procedure KickStart:
  if iDataSize < 13 THEN DO:
    SET-SIZE(mData) = 0.
    set-size(mData) = 13.
    iDataSize = 13.
    SET-BYTE-ORDER(mData) = BIG-ENDIAN.
   
   
    put-long(mData, 1) = length('WhatEver')+ 1.
    put-string(mData, 5) = 'WhatEver'.
    lRC=hSocket:WRITE(mData, 1, 13) NO-ERROR.
    IF lRC = FALSE OR ERROR-STATUS:GET-MESSAGE(1) <> "" THEN
    DO:
        message "Unable to write DetailBytees" view-as alert-box.
        return.
    END.

  END.
end procedure.    

procedure readProc:
  define variable mBuffer as memptr no-undo.
  /* I never see this message - I don't see that readProc ever gets executed */
  message "we are in read-response event procedure".

  set-size(mBuffer)=64.
  Self:read(mBuffer, 1, self:get-bytes-available()).
  message self:bytes-read "Bytes read".
  cString = get-string(mBuffer, 1).
  display cString format "X(70)".

end procedure.

Java Code:
Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
* A server program which accepts requests from clients to
* capitalize strings.  When clients connect, a new thread is
* started to handle an interactive dialog in which the client
* sends in a string and the server thread sends back the
* capitalized version of the string.
*
* The program is runs in an infinite loop, so shutdown in platform
* dependent.  If you ran it from a console window with the "java"
* interpreter, Ctrl+C generally will shut it down.
*/
public class CapitalizeServer {

    /**
     * Application method to run the server runs in an infinite loop
     * listening on port 9898.  When a connection is requested, it
     * spawns a new thread to do the servicing and immediately returns
     * to listening.  The server keeps a unique client number for each
     * client that connects just to show interesting logging
     * messages.  It is certainly not necessary to do this.
     */
    public static void main(String[] args) throws Exception {
        System.out.println("The capitalization server is running.");
        int clientNumber = 0;
        ServerSocket listener = new ServerSocket(9898);
        try {
            while (true) {
                new Capitalizer(listener.accept(), clientNumber++).start();
            }
        } finally {
            listener.close();
        }
    }

    /**
     * A private thread to handle capitalization requests on a particular
     * socket.  The client terminates the dialogue by sending a single line
     * containing only a period.
     */
    private static class Capitalizer extends Thread {
        private Socket socket;
        private int clientNumber;

        public Capitalizer(Socket socket, int clientNumber) {s
            this.socket = socket;
            this.clientNumber = clientNumber;
            log("New connection with client# " + clientNumber + " at " + socket);
        }

        /**
         * Services this thread's client by first sending the
         * client a welcome message then repeatedly reading strings
         * and sending back the capitalized version of the string.
         */
        public void run() {
            try {

           
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                // These messages appear when I start the Progress code.  Seems to work
                out.println("Hello, you are client #" + clientNumber + ".");
                out.println("Enter a line with only a period to quit\n");

                // I don't see that this ever gets executed

                while (true) {
                    String input = in.readLine();
                    if (input == null || input.equals(".")) {
                        break;
                    }
                    out.println(input.toUpperCase());
                }
            } catch (IOException e) {
                log("Error handling client# " + clientNumber + ": " + e);
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    log("Couldn't close a socket, what's going on?");
                }
                // I see this message when I close the Progress client
                log("Connection with client# " + clientNumber + " closed");
            }
        }

        /**
         * Logs a simple message.  In this case we just write the
         * message to the server applications standard output.
         */
        private void log(String message) {
            System.out.println(message);
        }
    }
}
 

Attachments

  • CapitalizeServer.java.txt
    3.9 KB · Views: 1
  • progress_socket.p
    2.3 KB · Views: 0
Last edited:

RealHeavyDude

Well-Known Member
In your ABL code, the input to the socket must contain a line break terminator '~n'. Otherwise nothing will be written onto the socket.
 

RealHeavyDude

Well-Known Member
This is in production and works for without a fuzz:
Code:
define variable terminator            as character   no-undo initial '~n'.

....

assign clientInputString = clientInputString + terminator.
set-size ( clientInput ) = length ( clientInputString ) + 1.
set-byte-order ( clientInput ) = big-endian.
put-string ( clientInput, 1 ) = clientInputString.
clientSocket:write ( clientInput, 1, length ( clientInputString ) ).
 
Top