From: Brian Candler Date: 2003-05-16T22:40:36+09:00 Subject: Re: TCP Sockets On Fri, May 16, 2003 at 10:26:59PM +0900, Dominik Werder wrote: > > That would mean mixing the binary streams in a non-deterministic way, > > which > > I think you need to understand the message boundaries within a stream for > > this sort of multiplexing to be useful. > Of course I'll take some data from Stream "1" and create a packet like > this: "Here we go with xx bytes from stream 1" and send this through my > "tunnel"-connection. > The problem: My program does not know about the underlaying protocol of the > stream. So if I receive 99 bytes from that stream, and these 99 bytes are a > request of any protocol and my task is to only forward this packet through > the tunnel, then I can hardly wait for, say, 100 bytes are available > because I did a read(100) and my process blocks until 100 bytes are > available :) Sure, using the method that Nobu proposes you might be able to tell that there are exactly 99 bytes sitting in the socket buffer right now. But how do you know that 99 bytes is a whole request? Maybe the whole request is 138 bytes, but because the message is sent in TCP chunks, the first read() returned 99 bytes, and the next read later returns 39 bytes. Or maybe it's two requests of 69 bytes each; the first read() returns the whole first request plus 30 bytes of the second request, and the the second read() returns the remaining 39 bytes. > >> How do for example P2P clients do that? One thread per connection? > > I don't know what you mean by 'P2P', but a server talking to multiple > > clients would indeed normally have a separate thread per client. There's > > an > > example of a fake pop3 server at > > http://www.rubygarden.org/ruby?SingletonTutorial > > (at the end of section 2) > I mean peer-to-peer, like filesharing clients. They got many concurrently > connections.. They'll have a separate TCP connection for each peer, and process messages from each stream independently. Since you are parsing all the incoming messages, you know where the message boundaries are. Ruby threads do this easily; or you can simulate it using select(); or you can fork off a separate process for each peer. Regards, Brian.