From: Robert Klemme Date: 2012-08-21T15:39:30+09:00 Subject: Re: TCPserver how to signal EOT On Tue, Aug 21, 2012 at 4:17 AM, tammy roberts2 wrote: > Robert Klemme wrote in post #1072878: >> On Mon, Aug 20, 2012 at 11:57 AM, tammy roberts2 >> wrote: >> This is a completely different approach: you do not use a termination >> byte any more but transmit the message length beforehand. >>> data_received = [] >>> end >>> >>> def send_data(socket, message) >>> forward_message = [message.bytesize].pack('N*') + message >>> socket.send(forward_message, 0) >>> yield(socket) >>> end >> >> Why do you yield the socket? > > So that it can be passed to the get_reply method if the client expects a > reply from the server, or closed by the calling method if it does not. Aha. The issue with that is that you can read only with one thread at a time from the socket. Since you created a thread after socket accept and that thread loops reading this should be the only thread fetching data from the socket. Sending is a different story (but btw. you should also properly synchronize to make sure only one thread writes at a time). >>> yield(reply, socket) >>> end >>> end >> >> If you use #send then I'd also use #read for reading instead of >> #recvfrom. I'd only use that method if I needed the extra options. >> Method #read will also block until as many bytes have arrived so you >> do not take care of fragment messages yourself. > > So am I correct in thinking that if I use read I do not need to put it > in a loop because it will always wait until that many bytes have > arrived? Yes, #read will block. But I confused method pairs: it should be #read and #write and not #read and #send. >> I'd probably choose a tad different approach by wrapping the >> connection with something that does the message handling and creation >> of a message type (for specific parsing etc.): > > The listen method currently yields to the caller an array with the parts > of the data that has been transmitted to it, and the calling method then > knows how to process this array depending on what it is (the message > type). No. Method #listen does not yield. It's the reader thread which you start in #listen. And note that this can be a problem if the block you pass in is not prepared to be executed concurrently. > Thanks for your advice I will be seriously considering the way you > presented this :). You're welcome! Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/