Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!cs.mu.OZ.AU!kre From: kre@cs.mu.OZ.AU (Robert Elz) Newsgroups: comp.protocols.tcp-ip Subject: Re: sockets vs. streams Message-ID: <5329@munnari.oz.au> Date: 2 Sep 90 17:59:27 GMT References: <6964@milton.u.washington.edu> Sender: news@cs.mu.oz.au Lines: 89 In article <6964@milton.u.washington.edu>, mrc@Tomobiki-Cho.CAC.Washington.EDU (Mark Crispin) writes: > > If "network I/O looks like local device I/O" under Unix then when the > h*ll do I have to worry about all the socket or streams crap? There was a time when building network names into the filesystem was seen as a sensible thing to do - nice and regular, existing programs would be able to use them, ... Unfortunately, while its a nice idea, it really won't work in general, and if it doesn't work in general, its not worth the effort. First, its perfectly reasonable for an application to check whether a file exists before attempting to open it, that way more meaningful error messages can be given - this is kind of hard to do with a network connection. Second, while your example gave numbers (/tcp/128....) that would be useless in practice - the interface would need to use names. Since "open" is a kernel routine (if we're not assuming that we're talking about completely different issues) that means that either name->number mapping needs to be done in the kernel, or the kernel needs to have some mechanism to get some kind of user process to do the mapping for it. Now assuming that this can be solved, the application needs to be able to select parameters for the mapping process - How many attempts should be made to find the translation? With what delay between attempts? Should default domains be appended? Which? Should some user defined nic-name to real name be applied? From where? What should be done with "soft" nameserver errors? Which server should we be using? Next, lets assume that that we are able to get the number, somehow, and the port number (from its name) as well - next we have to open the connection. At first sight that's easy - but how do we specify the MSS, receive and transmit windows, IP header TTL, TOS, ... You suggested that all of this could be built into the filename as optional segments (by now we're getting pretty far from the traditional notion of a filename, but never mind). Certainly, they could - but doing this makes the user (the provider of the filename) responsible for specifying all this crud - what does the user care about MSS's? So, instead the application has to massage the file name to append all of the various option settings that it might need (sure - most applications will take kernel defaults, but the mechanism has to be there - and all of this has to be done before the connection is opened). Now, the easy part is solved, TCP just isn't that complex, but lets extend generality a little and open an OSI MHS (X.400) connection as well. In the connection setup here we need various addresses, XSAP's (for various X), packet sizes, window sizes, numerous option selections at various levels, MTA names, passwords, ... By the time its all specified your pathname is going to be totally absurd. This is why the socket() call provides an anonymous file descriptor (and the streams model does much the same thing). Having that file descriptor all the necessary options can be set before the network is asked to establish the connection - simple applications may set none at all and rely on defaults, sophisticated applications might set many. But its one mechanism that works well for everyone. A better question might not be, to regularise things, why isn't all I/O done by first requesting a socket, then connecting to the object, ie: open(path, mode) might be modelled (very roughly) as s = socket(AF_FS, ...); setsockopt(FS_MODE, mode); connect(s, path, ...); (with bind() used for creat(0 of course). Henry Spenser asked why no-one has ever created a standard library routine to open a connection. That's something I have wondered about myself, it seems like a fairly obvious thing to do. But then I've never done it either ... I guess its just that opening a net connection (explicitly) just isn't something that is done all that often, and isn't really that hard when you need to do it, so neither I nor anyone else I'm aware of has bothered to define a good simple interface useful for most applications (this is a case where universal applicability wouldn't be needed - the underlying mechanism is still there when required, just as stdio's fopen() doesn't do everything that open() is capable of). kre