server app help!

tarloy

New Member
hi, all:
I have a very preplex problem with socket development of progress 9.1C.

I set read-response-procedure for socket handle which accept by server listened socket.
And I use "do while true:" statment to literate the "process event" statment.

In read-response event handle procedure, I invoke the SELF:GET-BYES-AVAILABLE() function to determine whether client disconnect or bytes available to be read.

The problem is: When i write a simple client to send messages to the server very fast( 10times per tick ). some times, the server get-bytes-available is zero, and then the server don't handle any event of socket, but the connection is keep alive.

anyone can help me!

The whole code below is the server code:
DEFINE VARIABLE nMAXConnection AS INT INITIAL 10.
/*
GLOBAL DEFINE
*/
DEFINE VARIABLE hServerSocket AS HANDLE.
DEFINE VARIABLE bRetVal AS LOGICAL.
DEFINE NEW GLOBAL SHARED TEMP-TABLE tmpTAB_ClientSocks
FIELD hClientSocket AS HANDLE
FIELD bConnected AS LOGICAL
.
/*
Initialize
*/
FOR EACH tmpTAB_ClientSocks:
DELETE tmpTAB_ClientSocks.
END.
DISPLAY "Starting Service....".
CREATE SERVER-SOCKET hServerSocket.
hServerSocket:SET-CONNECT-PROCEDURE( "OnConnectProc" ).
IF hServerSocket:ENABLE-CONNECTIONS( "-S 3334") THEN
DISPLAY "Starting Service OK!".
ELSE DO:
DISPLAY "Starting Service failed!".
RETURN.
END.
/*
Loop for listen client connect
*/
DO WHILE TRUE
ON STOP UNDO, LEAVE
ON QUIT UNDO, LEAVE:
PROCESS EVENTS.
END.

FOR EACH tmpTAB_ClientSocks WHERE bConnected = FALSE:
tmpTAB_ClientSocks.hClientSocket:DISCONNECT().
END.
EMPTY TEMP-TABLE tmpTAB_ClientSocks.
DISPLAY "test".
hServerSocket:DISABLE-CONNECTIONS().
DELETE OBJECT hServerSocket.
/*
OUTPUT CLOSE.
*/
PROCEDURE OnConnectProc.
/* Connection procedure for server socket */
DEFINE INPUT PARAMETER hClientSocket AS HANDLE. /*Socket implicitly created*/

DEFINE VARIABLE mSendBuffer AS MEMPTR.
SET-SIZE( mSendBuffer ) = 32.
CREATE tmpTAB_ClientSocks.
ASSIGN
tmpTAB_ClientSocks.hClientSocket = hClientSocket
tmpTAB_ClientSocks.bConnected = TRUE
.
RELEASE tmpTAB_ClientSocks.
hClientSocket:SET-READ-RESPONSE-PROCEDURE( "OnDataRecvd" ).
IF nMAXConnection > 0 THEN DO:
nMAXConnection = nMAXConnection - 1.
PUT-STRING( mSendBuffer, 1 ) = "authorization".
/*
hClientSocket:WRITE( mSendBuffer, 1, 13 ).
*/
RUN SOCKET_WRITE( hClientSocket, mSendBuffer, 13 ).
END.
ELSE DO:
PUT-STRING( mSendBuffer, 1 ) = "too many user.".
/*
hClientSocket:WRITE( mSendBuffer, 1, 14 ).
*/
RUN SOCKET_WRITE( hClientSocket, mSendBuffer, 14 ).
hClientSocket:DISCONNECT().
END.
SET-SIZE( mSendBuffer ) = 0.
PAUSE 1.
END.
PROCEDURE OnDataRecvd.
DEFINE VARIABLE nDataLen AS INT.
DEFINE VARIABLE nPacketLen AS INT.
DEFINE VARIABLE mRecvBuffer AS MEMPTR.
SET-BYTE-ORDER( mRecvBuffer ) = LITTLE-ENDIAN.
SET-SIZE( mRecvBuffer ) = 256.
nDataLen = SELF:GET-BYTES-AVAILABLE().
IF nDataLen > 0 THEN DO:
DO WHILE nDataLen > 0:
RUN SOCKET_READ( SELF, mRecvBuffer, 4 ).
nPacketLen = GET-LONG( mRecvBuffer, 1 ).
nPacketLen = nPacketLen - 4.
RUN SOCKET_READ( SELF, mRecvBuffer, nPacketLen ).
PUT-BYTE( mRecvBuffer, nPacketLen + 1 ) = 0.
MESSAGE "RECV DATA:" GET-STRING( mRecvBuffer, 1 ).
FOR EACH tmpTAB_ClientSocks WHERE bConnected = TRUE:
/*
tmpTAB_ClientSocks.hClientSocket:WRITE( mRecvBuffer, 1, nDataLen ).
*/
RUN SOCKET_WRITE( tmpTAB_ClientSocks.hClientSocket, mRecvBuffer, nPacketLen ).
END.
nDataLen = nDataLen - 4 - nPacketLen.
END.
END.
ELSE DO:
MESSAGE "RECV DATA ZERO".
END.
MESSAGE "RECV DATA COMPLETED!".

SET-SIZE( mRecvBuffer ) = 0.
END.
/*
auto send data complete.
*/
PROCEDURE SOCKET_WRITE.
DEFINE INPUT PARAMETER hSocketHandle AS HANDLE.
DEFINE INPUT PARAMETER mSendBuffer AS MEMPTR.
DEFINE INPUT PARAMETER nDataLen AS INT.
DEFINE VARIABLE nMemSeek AS INT INITIAL 1.
DO WHILE nDataLen > 0:
IF FALSE = hSocketHandle:WRITE( mSendBuffer, nMemSeek, nDataLen ) THEN DO:
MESSAGE "WRITE FAILED!".
RETURN.
END.
nDataLen = nDataLen - hSocketHandle:BYTES-WRITTEN.
nMemSeek = nMemSeek + hSocketHandle:BYTES-WRITTEN.
END.
END.

PROCEDURE SOCKET_READ.
DEFINE INPUT PARAMETER hSocketHandle AS HANDLE.
DEFINE INPUT PARAMETER mRecvBuffer AS MEMPTR.
DEFINE INPUT PARAMETER nDataLen AS INT.
DEFINE VARIABLE nMemSeek AS INT INITIAL 1.
DO WHILE nDataLen > 0:
IF FALSE = hSocketHandle:READ( mRecvBuffer, nMemSeek, nDataLen ) THEN DO:
MESSAGE "READ FAILED!".
RETURN.
END.
nDataLen = nDataLen - hSocketHandle:BYTES-READ.
nMemSeek = nMemSeek + hSocketHandle:BYTES-READ.
END.
END.
 
Just use a WAIT-FOR instead of the PROCESS-EVENTS loop. e.g.

WAIT-FOR "CLOSE" OF THIS-PROCEDURE. A WAIT-FOR is already "processing events" as they happen.

You should then find things are far more stable.
 

tarloy

New Member
thank you so much, mike.

I have improved my code, and the server is running more stably.

but however, sometimes when multi-point clients send data to the server quickly, it's get-bytes-available() equal zero and then the serve don't handle any event of socket but the connection is keep alive.
I find out another way to resolving the problem that is invoking the set-read-response-procedure again when zero bytes available on socket.

but I don't konw why the "this-procedure" release the event procedure processing.
 
Top