python-hl7 icon indicating copy to clipboard operation
python-hl7 copied to clipboard

read_stream() - message longer than RECV_BUFFER raises MLLPException('buffer not terminated...')

Open massimiliano-della-rovere opened this issue 8 years ago • 3 comments

The read_stream function reads just one chunk of data that must be at most RECV_BUFFER bytes long.

This breaks when a message is longer than RECV_BUFFER. The fix is keeping on executing

data = stream.read(RECV_BUFFER)

and break if len(data) < RECV_BUFFER.

I will post a patch proposal soon.

The solution you propose is still incorrect. The client may receive less data than could fit in the provided buffer even if that is not the entire message sent as a response by the server, in which case the client should continue reading.

ii8 avatar Aug 01 '18 08:08 ii8

I'm having the same issue but when using mllp_send. Were you able to find any fixes?

elamathis18 avatar Feb 11 '22 11:02 elamathis18

I'd love to have a patch for this. I think the whole implementation of https://github.com/johnpaulett/python-hl7/blob/6d85f25d678e366d2617690d4ee1216bb8027db1/hl7/client.py#L82 MLLPClient.send() is faulty. I think something like this might work:

    #make socket non blocking
    the_socket.setblocking(0)
     
    #total data partwise in an array
    total_data=[];
    data='';
     
    #beginning time
    begin=time.time()
    while 1:
        #if you got some data, then break after timeout
        if total_data and time.time()-begin> timeout:
            break
         
        #if you got no data at all, wait a little longer, twice the timeout
        elif time.time()-begin> timeout*2:
            break
         
        #recv something
        try:
            data = the_socket.recv(8192)
            if data:
                total_data.append(data)
                #change the beginning time for measurement
                begin=time.time()
            else:
                #sleep for sometime to indicate a gap
                time.sleep(0.1)
        except:
            pass
     
    #join all parts to make final string
    return''.join(total_data)

But I tried the above and it's still not fully working. But you get the idea, where there's a loop around the recv call from the socket to keep receiving data, that may come in chunks from the server.

anibal2j avatar May 25 '22 01:05 anibal2j