Jump to content

VTTB

Members
  • Content Count

    3
  • Joined

  • Last visited

Posts posted by VTTB


  1. I realize that the proposed solution is probably better but I'm still trying to  figure out what is happening here. I don't see a race between the threads here because they are mutually exclusive through a TCriticalSection, so the Receive Thread can never receive any other message than a KeepAlive because when a regular message is sent to the server the main thread holds the lock until the main thread has received the message, or a timeout occured (here lies the problem, the main thread is not receiving anything unless I read before I send and then read the answer)

     

    It also wouldnt be a problem the other way around. If the server would send a KeepAlive just when the Receive Thread has finished it's cycle and I'd then send a regular message from the main thread I should at least receive "garbage" in the main thread, but I receive nothing. Even if there'd be garbage that wouldnt be a problem, I'd just discard the KeepAlive and send the regular message because for the server that's also OK

     

    Between KeepAlive messages I have ~30 seconds to send and receive regular messages via the main thread without problems, even though the receive thread is checking for KeepAlive messages once a second and as soon as the receive thread has handled a KeepAlive message (received and answered, buffers are empty afterwards), the first regular message will fail, unless I read *before* I send. If there'd be something wrong with the bytes in the buffers I should at least receive garbage in the main thread, but I dont

     

    I will eventually redesign the thing but for now I'm curious why it's not working unless I read (and dont receive anything) in the main thread before sending and then reading again from the main thread.


  2. Good day,

     

    I'm supposed to communicate with a Server that receives XML messages and sends XML data back, occasionally (every 30 seconds when there were no other messages passed) the server sends a KeepAlive XML message without the client asking for it, but the client has to answer to the message. So I have a TReceiveThread class, derived from TThread, that gets passed the TIdTCPClient which was created in the main thread aswell as a TCriticalSection for synchronization, implemented .Execute to check once a second if a KeepAlive message arrived and sends an answer back to the server.

    .Execute (pseudo code):

    .Execute
    	while not Terminated
    		TThread.Sleep(1000)
    		lock.enter
    		try
    			try
    				recevied data (exception on timeout)
    				if message type is keepalive
    					send ack message
    			except
    			end
    		finally
    			lock.leave
    		end

    So far so good.

     

    Now I want to send other messages, for example on a button click from the main thread (pseudo code): 

     

    create xml message
    lock.enter
    try
    	try
    		send xml message
    		read data (exception on timeout)
    		parse data
    	except
    		report timeout error
    	end
    finally
    	lock.leave
    end

    This also works with every message I've implemented.

    However, when I'm not sending a message for 30 seconds so the server sends a KeepAlive message that gets handled and answered in the thread, the next message I'm trying to send from the main thread will throw a EIdReadTimeout (I can see the data sent in Wireshark, but not the data received). When I then send the same message again I'm getting an answer. I've extensively checked for synchronization errors and dead data in the send/receive buffers, that all seems to be fine. 

     

    when I change the code above to:

    create xml message
    lock.enter
    try
    	try
    		try
    			read data (exception on timeout) <------ 
    		except
    		end
    
    		send xml message
    		read data (exception on timeout)
    		parse data
    	except
    		report timeout error
    	end
    finally
    	lock.leave
    end

    as if the first read in the main thread somehow changes the context so the second read works as expected

     

    any advice?

     

     

×