Date: Fri, 15 Nov 1996 14:26:41 -0700 (MST) From: Terry Lambert <terry@lambert.org> To: jlemon@americantv.com (Jonathan Lemon) Cc: terry@lambert.org, jgreco@brasil.moneng.mei.com, jdp@polstra.com, scrappy@ki.net, hackers@FreeBSD.org Subject: Re: Sockets question... Message-ID: <199611152126.OAA27028@phaeton.artisoft.com> In-Reply-To: <199611152001.UAA28019@right.PCS> from "Jonathan Lemon" at Nov 15, 96 02:01:03 pm
next in thread | previous in thread | raw e-mail | index | archive | help
> > Otherwise, you have just un-formatted your transport contents. 8-(. > > TCP streams are byte oriented, not record oriented. There is no preservation > of record boundaries with TCP. I am talking about imposing structure on the stream on the basis of forcing the programs to communicate with the stream using record sized chunks. It's irrelevent what happens in the wire, or how the kernel chooses to copy the byte-oriented data into the user buffer on the receiver, so long as the receiver is not falsly notified that the request has been fulfilled. I admit that there is an implication here that I didn't take into account: That two writes to a socket will not be agregated across write buffer boundries into a single packet, OR that the receiver will read an amount such that if agregation occurs, it is irrelevent to the receiver's ability to distinguish the boundries. I have to say that SO_RCVLOWAT and SO_RCVTIMEO screw this considerably, in their roles as vmin/vtime equivalents. 8-(. My advice for someone building a transaction oriented protocol would be to set SO_RCVLOWAT to the same value as SO_RCVBUF, and to never, ever do packets larger than that as part of the formatted data. > > If you want to get technical, according to this description, if you are > > using a SOCK_STREAM, then a read on a blocking socket will act like a > > recv(2) or recvfrom(2) with flags MSG_WAITALL by default. > > read(2), recv(2), and recvfrom(2) all call soreceive() for sockets. read(2) > does NOT set MSG_WAITALL when calling soreceive(). Also: Well, this is probably an error for a blocking socket read, then... 8-(. > * If MSG_WAITALL is set but resid is larger than the receive buffer, > * we have to do the receive in sections, and thus risk returning > * a short count if a timeout or signal occurs after we start. > > So MSG_WAITALL can also return a short count. Only in case of a timeout or a signal, both of which are error conditions. The default behaviour for BSD prior to the introduction of siginterrupt() was to restart all system calls interrupted by signal. If the default behaviour is used, then the only possible failure would be EPIPE, indicating a timeout (loss of connection) (assuming a blocking socket). > > Maybe you should be using SOCK_SEQPACKET instead of SOCK_STREAM? > > That might be difficult. > > A SOCK_SEQPACKET socket [ .... ] is protocol specific, and presently > implemented only for PF_NS. (PF_NS == Xerox Network Systems protocols) Well, bummer deal. 8-(. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611152126.OAA27028>