Java Forum / General / February 2008
Java Socket Constructor
Terracotta - 18 Jan 2008 18:05 GMT Hi All:
We all know that "Socket(String host, int port)" create a client socket which connecting to the target host : port
however, which local port does it connect from? I guess it must be a random port from list of available ports. but how can we find out which port is currently been used?
I thought another constructor Socket(InetAddress address, int port, InetAddress localAddr, int localPort) might help. but the following code :
" Socket connection = new Socket("www.google.com", 80, InetAddress.getByName("localhost"), 0);"
doesn't work either. can anyone spot the problem please
Andreas Leitgeb - 18 Jan 2008 18:29 GMT > I thought another constructor > Socket(InetAddress address, int port, InetAddress localAddr, int localPort) > might help. but the following code : > Socket connection = new Socket("www.google.com", 80, > InetAddress.getByName("localhost"), 0); > doesn't work either. can anyone spot the problem please That may be a problem beyond java: localhost is typically 127.0.0.1, which is the "loopback" address.
It's like you were giving out visit-cards with your name written as "me", and address given as "my town". You can't expect to receive any answers that way.
Have you tried using the (seemingly synonymous) InetAddress.getLocalHost() ? It's docu is not very clear, but it seems like it would return the loopback- device only as a fallback under special circumstances, so it may look like it would return something more sensible, normally.
EJP - 28 Jan 2008 07:56 GMT > localhost is typically 127.0.0.1, which is the "loopback" address. Only on certain misconfigured Linux distributions. 'localhost' should be the first non-loopback IP address, not the loopback address.
> Have you tried using the (seemingly synonymous) > InetAddress.getLocalHost() ? Better still, have you tried 'null'? This always works.
Andreas Leitgeb - 28 Jan 2008 09:49 GMT >> localhost is typically 127.0.0.1, which is the "loopback" address. > Only on certain misconfigured Linux distributions. 'localhost' should be > the first non-loopback IP address, not the loopback address. All the machines within my reach (that is: where I do have an account on, most of them administered by professionals) which are linux, solaris, and one NetBSD, have localhost as 127.0.0.1, (the NetBSD machine has "::1")
I think, you mixed that up with the host's name (like "mypc") resolving to 127.0.0.1, which indeed was a common misconfiguration on many linux installations (mostly those that were installed as standalone machines, without even an ether-card). Other than home-machines with linux, unix- machines with no net at all are probably quite rare. So much for the correlation with linux).
>> Have you tried using the (seemingly synonymous) >> InetAddress.getLocalHost() ? > Better still, have you tried 'null'? This always works. I didn't see it documented anywhere. There is no mention of what happens for null InetAddress' in the javadoc for java.net.Socket. So, even if it appeared to work now and here, how can I know that it will still work in a different JVM, or even a future version of sun's JVM?
On further scanning of the javadoc-page, I saw, that behaviour for "null" is defined only for those constructors taking String arguments for addresses. So, this is not applicable to specifying the source-address, which is never given as String. InetAddress.getByName(null), which is used for null-String addresses, specifically gives the address of the *loopback-device*, so even if that was also used for null-InetAddresses, then it would still be the wrong address.
Lew - 28 Jan 2008 15:59 GMT >>> localhost is typically 127.0.0.1, which is the "loopback" address. >> Only on certain misconfigured Linux distributions. 'localhost' should be [quoted text clipped - 10 lines] > machines with no net at all are probably quite rare. So much for the > correlation with linux). FWIW, my experience correlates with Andreas's. A quick google for
> linux configuring localhost address finds: <http://www.redhat.com/docs/manuals/csgfs/browse/rh-cs-en/s1-hardware-linux.html> as the first link, in which the gurus state (ss. 2.4.1):
> 127.0.0.1 localhost.localdomain localhost as the canonical /etc/hosts file's first line.
Likewise, from "Configuring the Domain Name System DNS" <http://www.linux-tutorial.info/modules.php?name=MContent&pageid=148>:
> We also need a mapping for the node "localhost". > This is a special name for the local machine and is accessed using a [quoted text clipped - 4 lines] > > localhost IN A 127.0.0.1 <http://www.debian.org/doc/manuals/network-administrator/ch-bind.html>
> This allows mapping to and from your localhost which is 127.0.0.1. <http://www.oracle.com/technology/tech/php/htdocs/inst_php_apache_linux.html>
> You may need to replace "localhost" with the IP address 127.0.0.1 > or your machine's DNS name if you are behind a firewall > or if localhost does not resolve for some other reason. <http://faqs.org/faqs/linux/faq/part4/>
> Caution: Do not change the "localhost" entry in /etc/hosts, because > many programs depend on it for internal message-passing. bash $ man hosts ...
> EXAMPLE > 127.0.0.1 localhost
 Signature Lew
EJP - 29 Jan 2008 07:15 GMT > I think, you mixed that up with the host's name (like "mypc") resolving to > 127.0.0.1, which indeed was a common misconfiguration on many linux > installations Agreed, my mistake.
>> Better still, have you tried 'null'? This always works. > > I didn't see it documented anywhere. Null as a source-address means bind to the wildcard address (INADDR_ANY). Not the loopback device.
Andreas Leitgeb - 29 Jan 2008 08:18 GMT >>> Better still, have you tried 'null'? This always works. >> I didn't see it documented anywhere. > Null as a source-address means bind to the wildcard address > (INADDR_ANY). Not the loopback device. I do believe you, and it appears obvious, but I'm still curious if this is documented anywhere for java's Socket-class. That's just my pedantry :-)
PS: I did skim the javadoc-page for Socket, searching for all occurrances of "null", without ever finding it used for a source-address, so if it exists, it's either in a different page, or I missed it. (iirc, I had a look at the 1.4.2 version, which google spat out first, on searching for java & socket.
Peter Duniho - 29 Jan 2008 08:35 GMT >>>> Better still, have you tried 'null'? This always works. >>> I didn't see it documented anywhere. [quoted text clipped - 4 lines] > if this is documented anywhere for java's Socket-class. That's > just my pedantry :-) From Socket.bind(): http://java.sun.com/javase/6/docs/api/java/net/Socket.html#bind(java.net.SocketA ddress)
"If the address is null, then the system will pick up an ephemeral port and a valid local address to bind the socket".
To me, that seems to describe the same behavior you'd get from INADDR_ANY in BSD sockets (which is what I presume Esmond is referring to...I don't see any use of the actual name INADDR_ANY in the Java docs, though I could just be missing it, so I assume in the context of Java that's just shorthand for "0.0.0.0" or an equivalent representation).
I suppose technically 127.0.0.1 is a "valid local address" too, but it makes more sense to me that it would treat null as a wildcard address, not localhost.
Pete
Andreas Leitgeb - 29 Jan 2008 10:45 GMT > From Socket.bind(): "bind"ing is (iirc) something quite different: you wait for incoming connections with "bind"
Starting an outbound connection, even if a local address is specified will not "accept" any new connections, so I assumed that "bind" wasn't relevant to the concept of a source- address. (I may be wrong here)
The whole problem was, that to specify a local port (which may happen occasionally), there is no Socket-constructor that wouldn't also require a source address, but the source address is best picked by the system, depending on the target. The machine might be a router and be known to the inner net by a different ip, than on the other net. e.g. the outer net might not be able to reach the machine through some 10.x.y.z address, and the inner net might not even know the possibly dynamic IP-address of the ppp-dialup-link. So, if that router machines opens a connection to the inner net, then it had better pick the 10.x.y.z address, otherwise the externally known ip-address.
Peter Duniho - 29 Jan 2008 16:10 GMT >> From Socket.bind(): > > "bind"ing is (iirc) something quite different: > you wait for incoming connections with "bind" No, you wait for incoming connections with listen() (though, as near as I can tell, in Java this is done implicitly when you create a ServerSocket, rather than there being an actual listen() method...I'm more familiar with the lower-level sockets API than Java's wrapper around it). The bind() method is used simply to assign an address to a socket.
> Starting an outbound connection, even if a > local address is specified will not "accept" > any new connections, so I assumed that "bind" > wasn't relevant to the concept of a source- > address. (I may be wrong here) Yes, you are. A socket must be bound before it's used. You can call bind() explicitly, or it will be called on your behalf when you first try to use the socket in a context that requires a bound address. But the socket does get bound.
Your confusion may arise from the fact that most commonly a server socket (i.e. one that's listening) is bound explicitly (usually because you want a specific port), while a client socket (i.e. one that would connect to a listening socket) often need not be bound explicitly.
> The whole problem was, that to specify a local > port (which may happen occasionally), there > is no Socket-constructor that wouldn't also > require a source address, but the source > address is best picked by the system, depending > on the target. That's not a problem at all. Typically, providing INADDR_ANY is the way to do this. You provide an explicit port, and let the OS pick the IP address. Assuming Java behaves like the underlying OS, a server socket bound to INADDR_ANY will listen for and accept connections on any valid IP address, while a client socket will connect to a server using some specific IP address.
I admit, I haven't used the Java socket API specifically, but I would be very surprised if it deviated that much from the original socket API on which it's obviously based.
> The machine might be a router > and be known to the inner net by a different ip, [quoted text clipped - 6 lines] > better pick the 10.x.y.z address, otherwise the > externally known ip-address. If it uses INADDR_ANY, it should receive connection requests from either network. The socket will not receive an actual assigned IP address until it's been connected (for a client socket, after connect() has successfully completed, for a server socket, it's the socket returned from accept() that will have an assigned IP address, based on the connection made).
Pete
Nigel Wade - 29 Jan 2008 16:39 GMT >> From Socket.bind(): > > "bind"ing is (iirc) something quite different: > you wait for incoming connections with "bind" No, bind() simply binds a socket to an interface/port locally for both client and server sockets. At the system call level you would then listen() to wait for an incoming call, and finally accept() when a call arrived (if you wanted to allow the call). In Java this is rolled into the single accept() method of ServerSocket.
> Starting an outbound connection, even if a > local address is specified will not "accept" > any new connections, so I assumed that "bind" > wasn't relevant to the concept of a source- > address. (I may be wrong here) It is relevant. Every socket needs to be bound, either implicitly or explicitly, to an interface/port. At the system call level a socket is a bi-directional entity which can listen()/accept() and/or connect(). Java adds its own abstraction layer on top of this to create Socket, with only connect(), and ServerSocket, with only accept(). You can still bind a Socket (client) to a local interface/port if you want to, rather than accept the default.
> The whole problem was, that to specify a local > port (which may happen occasionally), there > is no Socket-constructor that wouldn't also > require a source address, but the source > address is best picked by the system, depending > on the target. The Socket() (i.e. no arguments) constructor creates an unbound client Socket(). You can bind this with Socket.bind(SocketAddress) to bind to a specific client port if you wish. After that you can connect() to a server. The other constructors perform the bind() and connect() with the supplied (or default) values.
> The machine might be a router > and be known to the inner net by a different ip, [quoted text clipped - 6 lines] > better pick the 10.x.y.z address, otherwise the > externally known ip-address. If it's a client socket then it would need to use the appropriate IP address for the server. It wouldn't matter whether this was on the LAN or the WAN side, using the IP of the server would be sufficient. If it was a ServerSocket being opened then you can either use the correct IP for the interface in question to only listen on that interface, or use the default which is to listen on all interfaces.
 Signature Nigel Wade, System Administrator, Space Plasma Physics Group, University of Leicester, Leicester, LE1 7RH, UK E-mail : nmw@ion.le.ac.uk Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
Andreas Leitgeb - 29 Jan 2008 20:55 GMT > [ some rusty remains of socket-API, which turned out to be > too rusty to actually describe what's going on. ] Thanks to Nigel and Peter for corrections & clarifications.
Arne Vajhøj - 30 Jan 2008 02:14 GMT >> From Socket.bind(): > > "bind"ing is (iirc) something quite different: > you wait for incoming connections with "bind" Bind just "allocates" the port.
It is normal to use bind for server usage to specify a specific port.
But you can use bind for client usage as well.
In fact I always do in my C code.
Arne
EJP - 29 Jan 2008 22:51 GMT > "If the address is null, then the system will pick up an ephemeral port > and a valid local address to bind the socket". This piece of documentation is incorrect. It doesn't pick a 'valid local address', it picks INADDR_ANY. That's not what I would call a 'valid local address' at all, it's the union of all local addresses.
> I don't see any use of the actual name INADDR_ANY in the Java docs It's in the documentation for InetAddress (the 'Unspecified address') and InetSocketAddress (the 'wildcard').
Lew - 30 Jan 2008 01:40 GMT >> "If the address is null, then the system will pick up an ephemeral >> port and a valid local address to bind the socket". > > This piece of documentation is incorrect. It doesn't pick a 'valid local > address', it picks INADDR_ANY. That's not what I would call a 'valid > local address' at all, it's the union of all local addresses. Now that is being picky. The result of INADDR_ANY could be considered a "valid local address" for the purposes of the class.
 Signature Lew
Carl - 18 Jan 2008 18:44 GMT > Hi All: > [quoted text clipped - 15 lines] > > doesn't work either. can anyone spot the problem please For starters, are you really expecting to bind at local port 0? I'd suggest you try a more sane number, as I'd suspect that passing a zero here causes the auto-assignment of the local port to take place.
Just out of curiousity, why do you want to specify the local port?
Mark Space - 18 Jan 2008 19:43 GMT > Hi All: > [quoted text clipped - 6 lines] > available ports. but how can we find out which port is currently been > used? connection.getLocalPort();
Peter Duniho - 18 Jan 2008 19:47 GMT > [...] > however, which local port does it connect from? I guess it must be a > random port from list of > available ports. but how can we find out which port is currently been > used? I'm pretty new to Java and haven't used sockets in Java yet. So I could be wrong about this. But in other socket implementations (BSD, Winsock, .NET Socket, etc.) once you've bound the socket, you can query the socket to find out the actual address and port that was used.
It looks to me as though the Socket.getLocalPort() function is how you'd do this in Java. Have you tried that? (After you've bound the socket to port 0, of course).
Pete
Arne Vajhøj - 19 Jan 2008 01:19 GMT > We all know that "Socket(String host, int port)" create a client > socket which connecting to [quoted text clipped - 4 lines] > available ports. but how can we find out which port is currently been > used? Mark S has already give you the method to get the port.
But what do you need it for ?
The other end can just write to the already opened connection and they can not even connect to that port you are looking for ?
Arne
Mark Space - 19 Jan 2008 02:40 GMT > But what do you need it for ? > > The other end can just write to the already opened connection and > they can not even connect to that port you are looking for ? Sometimes it's convenient to provide the port number with out exposing the Socket itself, or to stuff the port number into the payload/data so a higher level layer on the other end can retrieve it without having a low level API exposed.
Those are some reasons why I'd do it. I'll let the OP explain his own though.
Roedy Green - 29 Jan 2008 18:40 GMT On Fri, 18 Jan 2008 10:05:07 -0800 (PST), Terracotta <Junchen.Liu@gmail.com> wrote, quoted or indirectly quoted someone who said :
> however, which local port does it connect from? I guess it must be a >random port from list of >available ports. but how can we find out which port is currently been >used? See http://mindprod.com/jgloss/tcpip.html for a description of the protocol. Since this assignment is automatic and handled by the OS I can't think of a situation where it matters. You could watch it happening with a packet sniffer. See http://mindprod.com/jgloss/sniffer.html
The key thing to understand is that the assignment is unique only within incoming IP. Somebody cannot spoof being you simply by creating packets with your incoming port number on it.
 Signature Roedy Green, Canadian Mind Products The Java Glossary, http://mindprod.com
EJP - 29 Jan 2008 23:12 GMT > See http://mindprod.com/jgloss/tcpip.html for a description of the > protocol. No, you should see *RFC793* and *RFC1192* for a description of the protocol. Hobby pages can't possibly be a reliable source of information. Numerous errors I told this author about last year are are still there:
'It [TCP] is a symmetrical peer to peer protocol'. It is a client-server protocol.
'Java offers Socket.setSoTimeout to control how long you are willing to wait while the receiver blocks ... setSoTimeout has no effect on how long you are willing to wait for a read (how long you are willing to wait for the other end to produce data), just on how long you are willing for your write to complete (how long you are willing for the other end to keep advertising 0 buffer space for more incoming packets).' This is self-contradictory, and the part after ... is 100% back to front.
'I have found Java’s connection continuity testing to be less that 100% reliable.' Java doesn't have any connection continuity testing. There isn't any in TCP/IP either, other than the optional keepalive feature.
'[in keepalive] Each end with nothing to say just periodically sends an empty data packet with its current sequence, acknowledgement and window numbers.' If that was true it wouldn't provoke a response, so the keepalive feature wouldn't work. In fact RFC1192 says 'Such a segment generally contains SEG.SEQ = SND.NXT-1 and may or may not contain one garbage octet of data.'.
> Since this assignment is automatic and handled by the OS I > can't think of a situation where it matters. It matters with some over-configured client-side firewalls where an over-zealous netadmin has tried to restrict the outgoing port numbers. This is a misconfiguration exercise but it is encountered in practice.
'Thus the number of hops is not critical. What is critical is the bottleneck hop. (which varies since packets don’t take the precise same route).'
We discussed this before. What is critical is the *total delay,* whether compounded of lots of hops, or a long delay at a single hop, or anything in between. Typically there will be a large delay at ADSL connection points, and both the client and the server may have one of these.
Arne Vajhøj - 30 Jan 2008 02:18 GMT >> See http://mindprod.com/jgloss/tcpip.html for a description of the >> protocol. > > No, you should see *RFC793* and *RFC1192* for a description of the > protocol. Hobby pages can't possibly be a reliable source of > information. I assume that he uses information collected from the net.
Just yesterday someone posted:
#> localhost is typically 127.0.0.1, which is the "loopback" address. # #Only on certain misconfigured Linux distributions. 'localhost' should #be the first non-loopback IP address, not the loopback address.
...
Arne
Lew - 30 Jan 2008 04:04 GMT >>> See http://mindprod.com/jgloss/tcpip.html for a description of the >>> protocol. [quoted text clipped - 10 lines] > #Only on certain misconfigured Linux distributions. 'localhost' should > #be the first non-loopback IP address, not the loopback address. Funny, but I could not corroborate that "information" with anything I found on the 'net. /Au contraire/, I found plenty of corroboration that 'localhost' does indeed map to the loopback address, including in the command 'man hosts' on Linux.
So EJP has a point - it is wise to corroborate from authoritative sources, as I assume Arne intended to show as well.
 Signature Lew
Arne Vajhøj - 03 Feb 2008 03:17 GMT >>>> See http://mindprod.com/jgloss/tcpip.html for a description of the >>>> protocol. [quoted text clipped - 19 lines] > So EJP has a point - it is wise to corroborate from authoritative > sources, as I assume Arne intended to show as well. My point was more about posting style ...
Arne
EJP - 31 Jan 2008 06:02 GMT > I assume that he uses information collected from the net. Does that matter?
> Just yesterday someone posted: Sure, I did indeed, but I also accepted correction, in the same place it was posted, and also I didn't post it on a website entitled 'Java glossary' and recommend it left right and centre as an authoritative source ...
Arne Vajhøj - 02 Feb 2008 04:58 GMT >> I assume that he uses information collected from the net. > [quoted text clipped - 6 lines] > glossary' and recommend it left right and centre as an authoritative > source ... Ah.
It is more OK to post wrong info to usenet than to put it on a web site.
Or ?
A couple of famous quotes: * "He who is without sin among you, let him be the first to throw a stone at her." * "Treat others as you would like to be treated."
Arne
EJP - 03 Feb 2008 23:03 GMT > It is more OK to post wrong info to usenet than to put it on a web site. It is more OK to (a) recommend RFCs, and it is also more OK (b) post to usenet or elsewhere, making sure you punctiliously acknowledge and correct all errors you make in the process, than it is to (c) construct a hobby site with no well-defined review/editing/problem report process, (d) recommend it all over the place as an authoritative source, and (e) ignore all suggestions and comments for years on end and/or (f) take them as personal insults.
Tim Smith - 31 Jan 2008 02:19 GMT > information. Numerous errors I told this author about last year are are > still there: > > 'It [TCP] is a symmetrical peer to peer protocol'. It is a client-server > protocol. That seems a bit picky. Connection establishment is not symmetrical, but once the connection is established, it is symmetrical.
 Signature --Tim Smith
EJP - 31 Jan 2008 05:52 GMT > That seems a bit picky. Connection establishment is not symmetrical, > but once the connection is established, it is symmetrical. Agreed, but what he actually writes is this:
'It is a symmetrical peer to peer protocol. Either client or server could initiate the connection.'
John W. Kennedy - 31 Jan 2008 21:36 GMT >> That seems a bit picky. Connection establishment is not symmetrical, >> but once the connection is established, it is symmetrical. [quoted text clipped - 3 lines] > 'It is a symmetrical peer to peer protocol. Either client or server > could initiate the connection.' It is still partly true, in FTP. And the case of X is notorious, where the "client" is the server and the "server" is the client.
If you /define/ the "client" and the "server" according to the roles they take in establishing the connection, why, then, yes, only the "client" can initiate. But there are cases where insisting on this terminology, once the connection is made, can lead to madness.
 Signature John W. Kennedy "Give up vows and dogmas, and fixed things, and you may grow like That. ...you may come to think a blow bad, because it hurts, and not because it humiliates. You may come to think murder wrong, because it is violent, and not because it is unjust." -- G. K. Chesterton. "The Ball and the Cross"
Gordon Beaton - 01 Feb 2008 06:40 GMT > And the case of X is notorious, where the "client" is the server and > the "server" is the client. In X, the display is the server and the application is the client. The client initiates the connection. What's notorious about that?
/gordon
--
Arne Vajhøj - 02 Feb 2008 04:50 GMT >> And the case of X is notorious, where the "client" is the server and >> the "server" is the client. > > In X, the display is the server and the application is the client. The > client initiates the connection. What's notorious about that? Often the X client is running on a box that is called server and the X server is running in a box called client.
Arne
Lew - 02 Feb 2008 04:54 GMT >>> And the case of X is notorious, where the "client" is the server and >>> the "server" is the client. [quoted text clipped - 4 lines] > Often the X client is running on a box that is called server and > the X server is running in a box called client. True, but not necessarily a case for notoriety.
The point that comes clear is that "client" and "server" definitions are specific to the communication under discussion. The X client is the logic server, but the X client is only a client in the context of the X communication.
One can get poetic, as JWK did about that, but the rhetorical device depends on eliding the context shift between the channel devoted to application logic and that devoted to graphical display.
Maybe it's the attempt to obfuscate via that elision that deserves to be notorious.
 Signature Lew
EJP - 01 Feb 2008 07:31 GMT > If you /define/ the "client" and the "server" according to the roles > they take in establishing the connection, why, then, yes, only the > "client" can initiate. But there are cases where insisting on this > terminology, once the connection is made, can lead to madness. I'm not insisting on it once the connection is made. I'm insisting on it w.r.t. establishing the connection, since this is the context of the original statement. Saying '... the server can initiate the connection' is just nonsense for TCP. It can't. It can only accept it.
Lew - 01 Feb 2008 13:01 GMT >> If you /define/ the "client" and the "server" according to the roles >> they take in establishing the connection, why, then, yes, only the [quoted text clipped - 5 lines] > original statement. Saying '... the server can initiate the connection' > is just nonsense for TCP. It can't. It can only accept it. To expand on that- to abuse the terminology and /not/ refer to the initiator as "client" and the receiver as "server" is the way to madness. Engineering disciplines require precision of expression. TCP is set up such that only one end can initiate the connection - regardless of what you call it - as EJP pointed out. By definition the end that must initiate is called the client. John seems to say that there's something illegitimate about that. There isn't.
This business about
> the case of X is notorious, where the "client" is the server and the "server" is the client. is pure obfuscatory nonsense. Only one end of an X connection is the client, and only that end gets to be called the client. Likewise for the other end being the server. There is no "client is the server" going on at all. The client is the client, and the server is the server. Gordon Beaton straightened that one out. Don't be fooled by cute but totally inaccurate rhetoric.
 Signature Lew
Arne Vajhøj - 02 Feb 2008 04:48 GMT >>> If you /define/ the "client" and the "server" according to the roles >>> they take in establishing the connection, why, then, yes, only the [quoted text clipped - 12 lines] > regardless of what you call it - as EJP pointed out. By definition the > end that must initiate is called the client. I would say that I have seen client and server terms used in a per layer basis.
Meaning that in X--Y then X can be client at the TCP level but Y can be client at the application protocol level.
Arne
Lew - 02 Feb 2008 04:58 GMT Lew wrote:
>> To expand on that- to abuse the terminology and /not/ refer to the >> initiator as "client" and the receiver as "server" is the way to >> madness. Engineering disciplines require precision of expression. >> TCP is set up such that only one end can initiate the connection - >> regardless of what you call it - as EJP pointed out. By definition >> the end that must initiate is called the client.
> I would say that I have seen client and server terms used in a > per layer basis. > > Meaning that in X--Y then X can be client at the TCP level but > Y can be client at the application protocol level. Absolutely. The two points are complementary. The client at the TCP level is by definition the initiator of the TCP communication. The client at the app protocol level initiates app protocols.
By pointing out the importance of specifying to which layer the client-server distinction applies, you have increased the precision of expression. That is good engineering.
 Signature Lew
Martin Gregorie - 02 Feb 2008 16:52 GMT > Absolutely. The two points are complementary. The client at the TCP > level is by definition the initiator of the TCP communication. The > client at the app protocol level initiates app protocols. It seems to me that there's a more general way of looking at it:
A server advertises services for use by client processes. To do that it MUST have a known address which clients go to in order the user the services.
A client doesn't advertise anything and so doesn't need a known address. There is no way that a client can provide a service because there is no way to know its address until it contacts a server and starts to use the service that the server provides.
This applies regardless of the transport protocol being used to carry the service. It is fairly obvious in the case of TCP/IP because connection is non-symmetric: the server MUST be listening for connections, i.e. requests to the service it provides, but the client never does. Other examples:
- in the *NIX world a server can listen to a named pipe to advertise an service that's not available outside that host.
- An X.25 network is peer to peer in exactly the same way as POTS is, but a service can't be used unless there's a process that's prepared to accept incoming calls.
- 3270 bisync is the opposite: the entire transport protocol is controlled by the server. If that's not running, the terminals can't do anything.
- X-term fits the same pattern once you realize that an X server is providing display and input services to an application program. Another clue is that many applications can connect to a single X-term server but no X-term can connect to even one application.
- FTP is the really strange case. When you start FTP, the user program (client) connects its command channel to the daemon (server). Again, the daemon advertises its service on a known host's port.
The confusion happens when a file transfer is requested because a new data channel must be opened to shift the file contents before being closed. If you're running in PASSIVE mode its the same: the server returns a port number as part of its ACK and the user program connects to that port, reads the data, and closes the port. No problem. However, in classical mode the user program sends the daemon a port that it wants to listen on and then becomes a server. The daemon acts like a client and connects to the user program, sends the file and closes the connection. Then both programs revert to their original roles
> By pointing out the importance of specifying to which layer the > client-server distinction applies, you have increased the precision of > expression. That is good engineering. Agreed.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
John W. Kennedy - 02 Feb 2008 05:15 GMT >>> If you /define/ the "client" and the "server" according to the roles >>> they take in establishing the connection, why, then, yes, only the [quoted text clipped - 24 lines] > server. Gordon Beaton straightened that one out. Don't be fooled by > cute but totally inaccurate rhetoric. And FTP Active Mode dissappears in a puff of logic.
 Signature John W. Kennedy A proud member of the reality-based community.
Lew - 02 Feb 2008 06:21 GMT > And FTP Active Mode dissappears in a puff of logic. I think we're running into a layer issue here. As I understand FTP, the "server" from the app standpoint is the one to whom requests are made. Active and passive FTP are lower layer matters dealing with the network or transport, no?
 Signature Lew
John W. Kennedy - 03 Feb 2008 01:08 GMT >> And FTP Active Mode dissappears in a puff of logic. > > I think we're running into a layer issue here. As I understand FTP, the > "server" from the app standpoint is the one to whom requests are made. > Active and passive FTP are lower layer matters dealing with the network > or transport, no? FTP runs on two sessions, a command session and a data session. The command session is initiated by the client; that part is easy. In classic FTP, the data session is then initiated by the FTP server. Because this nowadays typically causes firewall problems at the client, a new "passive mode" FTP has been defined, in which, instead of initiating the data session, the server requests the client, via the command session, to initiate it, "active mode" being a retronym for the original design. Passive mode must be requested explicitly, since not all software supports it.
I don't know why they didn't just use a single session with a side channel implemented in the data format in the first place, unless it was simply to squeeze out the last drop of bandwidth.
So it may be technically correct to say, in describing how to program for TCP, that it is always the client, by definition, that initiates the session. But when explaining to someone who has just asked, "What is TCP?", to whom "the server" means "the big box in the air-conditioned room" and "the client" means "my PC", it is a pragmatic truth that "TCP sessions may initiate with either the client or the server". To tell him, "A TCP session always originates with the client," will only make him believe a dangerous falsehood, and explaining the whole situation runs the risk of making him go all Blanche DuBois on you ("My head is swimming!"), at least in my experience.
If he needs to know more later, then we can say, "When setting up a TCP session, the side that initiates it is always called the 'client', no matter what happens after the session is set up." Anyone who needs to know that will readily understand it.
 Signature John W. Kennedy "Cricket is a game where you have 2 sides - one out in the field and the other in, off the field. Each man in the side that is in, goes out, and when he is out, comes in, and the next man goes out until he is out, then he comes in. When the side that is in, goes out, they go in to get the others which are in, out. Sometimes you get men still in, but not out, but they are out. They go in when the side goes out, to be put in, but not out. When both sides have been in and out, even those that are not out, but also not in, that is the end of the game." -- Anon.
-- John W. Kennedy "There are those who argue that everything breaks even in this old dump of a world of ours. I suppose these ginks who argue that way hold that because the rich man gets ice in the summer and the poor man gets it in the winter things are breaking even for both. Maybe so, but I'll swear I can't see it that way." -- The last words of Bat Masterson
Lasse Reichstein Nielsen - 03 Feb 2008 01:38 GMT [FTP data transfer]
> Because this nowadays typically causes firewall problems at > the client, a new "passive mode" FTP has been defined, in which, > instead of initiating the data session, the server requests the > client, via the command session, to initiate it, "active mode" being a > retronym for the original design. Passive mode must be requested > explicitly, since not all software supports it. Actually, passive mode data transfer has been in the FTP protocol almost since the beginning (RFC 542 from 1973). It is not new, and not caused by firewalls.
It is true that the growth of private computers, possibly behind firewalls, or just NAT routers, and using browsers as FTP clients have cause passive FTP connections to become much more prevalent.
> I don't know why they didn't just use a single session with a side > channel implemented in the data format in the first place, unless it > was simply to squeeze out the last drop of bandwidth. Having separate data and control lines, along with both passive and active data transfer, allow you to use two control lines to initiate a direct transfer between two FTP servers, controlled by a third computer. Pretty nifty, actually.
/L
 Signature Lasse Reichstein Nielsen - lrn@hotpop.com DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html> 'Faith without judgement merely degrades the spirit divine.'
John W. Kennedy - 03 Feb 2008 02:45 GMT > [FTP data transfer] >> Because this nowadays typically causes firewall problems at [quoted text clipped - 7 lines] > almost since the beginning (RFC 542 from 1973). It is not new, and > not caused by firewalls. Thanks. I didn't know that. (I wrote my first e-mail server in the late 60s, but didn't get involved with TCP/IP until the Mosaic era.) That makes it a good deal more disturbing, though, that there are still servers out there that don't support passive mode.
 Signature John W. Kennedy A proud member of the reality-based community.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|