Java Forum / General / May 2005
peer to peer messaging
Bond - 25 May 2005 13:34 GMT Hi! I want to write an application that will send a message to another computer using Sockets. I've wrote a simple echo client server before using Sockets but this application is different. I want to be able to send a message to any other computer running this application. *** The problem that I'm running into is that when setting up the socket, if the computer is hooked up in a network, I know the IP address of the router... somehow I have to be able to send it directly to the computer... how can I do this? When a user uses the application, they log in and if there is any information I can store on the server that would help me do this, I can... any help would be great. Thanks!
Guy Noir - 25 May 2005 13:41 GMT As long as you know the destination IP address of the other machine, the IP address of your router should be irrelevant, as that is taken care of by the lower layers. That is, Java does not concern it's self with the routing. That's the job of the OS.
HTH -Aaron
Bond - 25 May 2005 14:41 GMT You say that the IP address of the router is irrelevant, but wouldn't that be the addess that I would have to provide when setting up the Socket? I wouldn't be able to just use the address of my local machine because that only means something to the router. For instance, I can't remember the ip address but it would be something like 101.0.0.1 (something stupid)... which is just something used to route from the router... I don't see how my application could send a message from one PC to another by using only the IP address of the router... how would the router know which machine on the network to forward the message to?
Guy Noir - 25 May 2005 15:05 GMT OK. So you are talking about Natting. Yes, it's true you would need to know the "Real World" ip address. You weren't clear earlier that you are talking about a NAT'ed connection. I assumed you meant you needed to pass an IP Packet to the router to reach a remote subnet. So, In your router, you would map a port forward.
Let's say you are using port 1234 for your server-socket. Let's assume your real IP addy is 208.1.1.10 and your internal IP is 10.0.0.20
In your router's firewall/NAT area, you need to set up a port forward so that when a connection attempt is made to 207.1.1.10 on port 1234, it forwards the request to your internal server at 10.0.0.20:1234.
Of course, you can only map to one internal machine on port 1234 if you only have 1 "real" ip address.
HTH -Aaron
Thomas Weidenfeller - 25 May 2005 15:22 GMT > Hi! I want to write an application that will send a message to another > computer using Sockets. I've wrote a simple echo client server before [quoted text clipped - 3 lines] > problem that I'm running into is that when setting up the socket, if > the computer is hooked up in a network, It would be a problem if the computer is *not* "hooked up" in a network. No network connection, no way to connect to it (ignoring the local loop for the moment). Was that sentence really meant as you wrote it?
> I know the IP address of the > router... Which router? Anyhow, routers are irrelevant when addressing a remote computer - the routers and the routing "just" has to be configured correctly in advance. You do not address a router directly when you want to connect to some computer behind that router. You still use an IP address for the computer, not for the router. If you have a name instead of an IP address, also fine. This will just require an additional DNS request to translate the name to the IP address of the computer - of course assuming that DNS for the computer has been set up correctly.
> somehow I have to be able to send it directly to the > computer... If there is no direct route, you simply can't. But that is not a problem. The job of a router is to route your packets to the intended destination by choosing an appropriate next hop. Why do you want to circumvent these helpful devices?
BTW: The first routing usually already happens inside your own computer. Your computer's routing table is consulted to decide which next hop should be used, and which physical interface.
> how can I do this? When a user uses the application, they > log in and if there is any information I can store on the server that > would help me do this, I can... any help would be great. Thanks! Which server? A central one? Didn't you say you want to implement a P2P application. What information? Storage?
I am usually flamed for the following advice, but I am used to it, so here it comes:
Please get a pen and paper and make up your mind what you really want. Sort your thought, sort out your terminology and read a textbook. You seem to be confused about how this whole IP networking thing works. A good introduction could help here. It is not only a good idea to know the basics when starting to design a networking application, but it is invaluable knowledge when you have to start to troubleshoot your application.
Comer, Douglas E.: Internetworking with TCP/IP Vol 1.
or the late W. R. Stevens'
Stevens, W. R.: TCP/IP Illustrated, Vol.1 : The Protocols
come to mind. Any good library should have it, too.
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
Bond - 25 May 2005 16:31 GMT Hi! I know exactly what I want... I just didn't know how much details I would have to provide for you to understand what I want to do.
I'm creating an application like your typical msn messenger. Here's how my application will work:
I have users (clients) that will create an account... this information is sent to A central server where it will be stored into a database. Users can add other users to their addressBook. The database will store information like the user's username, publicKey (ignore this), and status (whether they are online or not). This is helpful so that when a user signs in, an address book is created from the server (including all the contacts that the user added) and then send the addressbook back to the user. Please keep in mind that up to this point I have been using RMI... I've pretty well completed all of this.
The problem comes now... When the user goes to send a message, it will use a socket connection to do so. All that RMI stuff was just for authentication and other crap (setting up). Now for actual messaging I'm dealing with Sockets. Now, up above a guy mentioned port forwarding... i've done this before where I had to go into the Router settings and forward certain ports to my machine. That's fine but I know you don't have to do this for normal msn... so how does msn work for sending a message from one machine to another?
Anyways, hopefully this explains my application a little more clearly.
Thanks!
Thomas Weidenfeller - 25 May 2005 16:53 GMT > Hi! I know exactly what I want... As I wrote I am used to get flamed for telling people. Just to point out some things that still don't add up in your description or your usage of terminology: Your subject line says peer to peer. In your description you talk about a central server. You are mixing up routing function and - I would guess - NAT. You keep insisting that the usage of sockets is the issue (hint RMI is implemented on top of the same API). If you use a NAT device, then the direction of the connection setup, and not the socket, is the issue. You might want to study UPnP, or you might not.
I am to tired to sort it out for you.
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
Guy Noir - 25 May 2005 16:56 GMT > Hi! I know exactly what I want... I just didn't know how much details > I would have to provide for you to understand what I want to do. [quoted text clipped - 19 lines] > settings and forward certain ports to my machine. That's fine but I > know you don't have to do this for normal msn... Ahh BUT the MSN *server* is sitting outside of your natted network and when it does a getaddress() method or whatever, your firewall/NAT returns the real IP address and not the "Natted" address. So in short, if you want this to work "like MSN" your server will need a REAL ipaddress and not behind a NAT.
>so how does msn work > for sending a message from one machine to another? > > Anyways, hopefully this explains my application a little more clearly. > > Thanks! Bond - 25 May 2005 18:27 GMT when you say if I want this to work I will need a REAL ipaddress and not behind a NAT.... do you mean behind the same NAT? Would this work if I ran the server code on some other machine behind a different NAT?
Bond - 25 May 2005 18:35 GMT I find it funny how I was able to run a server on my own machine and then create a client that would connect to the server using Sockets and the server would echo back... the client side would randomly choose to connect to the localhost server or a server on another machine. The server would echo back the same message that it recieved. So what information did that server use to echo back that information to my machine that was connected to a router? Cause if i knew this information, it would solve my problem.
Guy Noir - 26 May 2005 16:06 GMT Start with 2 machines on the same subnet. Get your services working and then work your way out to dealing with NAT issues.
IMHO -Aaron
Tim Ward - 26 May 2005 16:40 GMT > Start with 2 machines on the same subnet. Get your services working and > then work your way out to dealing with NAT issues. Coo! That's clever! Then when you find that your system architecture cannot be extended to work across NAT boxes you just go to your boss and/or client and tell them that you've wasted your time and their money so far, now you need to start again from scratch to design a system that's actually going to be useful!
Not a career-enhancing approach, I would suggest.
-- Tim Ward Brett Ward Limited - www.brettward.co.uk
Chris Uppal - 26 May 2005 17:56 GMT > > Start with 2 machines on the same subnet. Get your services working and > > then work your way out to dealing with NAT issues. > > Coo! That's clever! Then when you find that your system architecture > cannot be extended to work across NAT boxes you just go to your boss > and/or client and tell them that you've wasted [...] Since NAT is supposed to be transparent to both ends of the network connection, it isn't obvious to me what the potential showstoppers might be ?
(Yes I do know that it's possible to [mis?-]design protocols so that they require active cooperation from the NAT, but does anyone actually design such protocols these days ?)
-- chirs
Bond - 26 May 2005 19:45 GMT maybe it's possible if I run a server on a machine that's not within subnet... then when people log on to my application, it opens a connection using Sockets with the server and then when the user wants to send a message, there will be an open connection to the end user. bah! lol... sounds like more work than it has to be.
Tim Ward - 27 May 2005 13:23 GMT > Since NAT is supposed to be transparent to both ends of the network connection, Eh?? Since when?? How can it be?? (Unless of coures you choose to restrict yourself to protocols that you have checked that all the NAT boxes on the path understand ... but of course the fact that you have to acquire such knowledge is itself a breach of transparency.)
> it isn't obvious to me what the potential showstoppers might be ? These days the IP address of any particular machine is different from different places, and the machine itself probably won't know all the IP addresses it can be referred to from all parts of the internet and private subnets.
I'd have thought the potential showstoppers *were* obvious:
If machine A which knows its IP address is X can talk to machine B via IP address Y then we have no way of knowing
(a) what IP address machine B thinks it has (b) what IP address machine B should use to talk to machine A (c) what IP address machine C should use to talk to machine B (d) on which of its interfaces B would be best advised to listen for connections from machine C
and so on and so on and so on.
All these things will work fine on singled homed machines on a LAN and most of them will fall over with only one single simple NAT box in the way.
-- Tim Ward Brett Ward Limited - www.brettward.co.uk
Chris Uppal - 31 May 2005 12:42 GMT [It's a bit late to reply, but maybe this'll be of interest to someone]
> If machine A which knows its IP address is X can talk to machine B via IP > address Y then we have no way of knowing [quoted text clipped - 6 lines] > > and so on and so on and so on. I think that we may be talking about different things, since what you say doesn't seem to make sense to me. I'll run through my understanding of NAT since that might be of some help to "Bond", or even of interest to yourself. (BTW, this has turned out much longer than I planned -- sorry about that.)
The thing to remember is that the Internet wasn't designed with NAT in mind. In fact NAT is an attempt to "fix" the way that the Net works without either of the end-point machines being aware of it.
Start with a simple case, with no NAT-ting involved anywhere. Say my laptop is connected to the Internet in the old-fashioned way, and that it attempts to the HTTP server at 209.249.116.141 (I'll ignore named IP addresses like 'java.sun.com' completely in this; they are not relevant since they are resolved before any of the stuff we are talking about happens). My machine attempts to open a connection to port 80 of the server at that IP address. The server responds by setting up a connection, and thereafter my machine and the server can communicate by sending IP packets with the appropriate port numbers embedded in them. For example a packet from my machine might have source IP aaa.bbb.ccc.ddd, and source port 3872 (randomly allocated when it attempts to make the connection) and destination address 209.249.116.141 and port 80. Packets from the sever to my laptop would have those reversed. Here, "my" IP address (aaa.bbb.ccc.ddd) is allocated by the relevant networking authorities, and has been assigned to me, and any machine anywhere on the network can address my machine using that address. (The same is true of the server's address too, of course.)
A couple of things are worth noting since they'll become relevant later. Neither my machine nor the server are interested at all in the addresses of any routers in between us (the TCP/IP implementation on each machine does have to know about the /nearest/ router, so that it can route packets via it, but that knowledge is only used by the TCP/IP implementation in the OS kernel or wherever, it is not needed or used by ordinary network programmers). Secondly, the quadruple of <source-port, source-IP, destination-port, destination-IP> is sufficient to "label" packets as belonging to a specific TCP/IP connection between one program running on my machine and one program running on the server.
Now let's assume that my laptop is not connected directly to the whole Internet, but is instead on a NAT-ed subnet connected to the real Net by a NAT-ing router. In this case, the router itself "sits on" my public IP address (which may not be all that public if it's temporarily allocated by my ISP, or it may be fixed and well-known with DNS entries and everything). So it is at address aaa.bbb.ccc.ddd. My own laptop is probably given an IP address from the "private use" range. Say it's 192.168.0.20. Other machines on the same subnet have IP addresses in the same private use range, but none of them have (I hope!) the exact same address.
Now, when my laptop attempts to connect to any other machine it will use that machine's IP address (as supplied by DNS presumably), and it's own IP address, 192.168.0.20, as the source address. It does that because that what it thinks its address is, and that's how TCP/IP works. For machines on my subnet that "just works", but when I attempt to connect to the server 209.249.116.141 then things would go wrong. If nothing intervened, then it would connect to 209.249.116.141 saying that the packets came from 209.249.116.141. If the server replied at all (which it probably have been configured not to) then the return packet would go missing, since the network as a whole has no idea how to route a packet addressed to 209.249.116.141 back to my laptop. But something /does/ intervene. What's more, it intervenes /transparently/. Somewhere between my laptop and the "real" Net is my NAT-ing router. When it sees a packet emanating from my laptop (or anywhere else in the NAT-ed subnet that it manages), it changes that packet so that it appears to come from its own IP address, aaa.bbb.ccc.ddd, and from a port number that it has temporarily allocated. It remembers that it is now managing a NATed connection for that IP/port. The server sees this packet just as before, and replies just as before. The reply ends up back at my router, which inspects the packet, and sees that the destination IP/port are for a connection that it knows about. It looks that data up in its internal list of connections, and finds the IP/port that my machine originally used. It changes the incoming packet to use that destination IP/port and sends the packet on to my machine.
The end result of all that is that my machine and the server can communicate in traditional TCP/IP way, even though my machine is not at a public IP address. As I said the NAT-ing is transparent, neither the network program (Firefox, say) nor my machine's OS know anything at all about the NAT (and there's nothing that they could usefully do with the knowledge if they had it).
OK, let's make it a bit more complicated. Now I'm going to set up a public web server on my laptop. I want anyone on the web to be able to connect to http://aaa.bbb.ccc.ddd/ and end up talking to my server. I can easily start an HTTP server on the laptop, but the problem is that it will be listening on port 80 at address 209.249.116.141. Not at aaa.bbb.ccc.ddd, which is a completely different address owned by my NAT-ing router. So what I have to do is go configure the NAT part of the router so that it knows that I want to allow connections to port 80 of my machine from the network as a whole (I'll probably have to change the firewall configuration too, but that's a different story). I tell it that when it sees an incoming packet aimed at port 80 of IP aaa.bbb.ccc.ddd, that it should do the same kind of packet modification as before to change the destination address to that of my own machine, and then forward the packet onwards. Similarly when it sees a packet going back on the same connection, it should re-write that package's source IP so that it seems to be coming from aaa.bbb.ccc.ddd.
Again, once I've done a little manual configuration, the whole process is transparent to both the webserver running on my laptop, and to the client machine somewhere on the Web.
There are a couple of potential problems with this. In the above description, the NAT can keep track of which connections it is modifying because it can track the TCP protocol as it opens and closes the connection. For connectionless protocols such as UDP/IP that isn't possible. So it has to use some sort of heuristic to attempt to keep the re-write information around for as long as it will be needed, but not clog up memory by keeping it for too long. (Actually, there's a similar problem with TCP/IP traffic, since the connection may be dropped without the normal shutdown messages being exchanged -- e.g. if one machine crashes). In theory this is a problem, but it doesn't seem to be too hard to solve in practice.
The other class of problem is caused by a handful of rather weird protocols (FTP comes to mind) which embed IP addresses and port number in the body of the protocol. In such cases there are only two answers. Either the NAT-ing router can "understand" that protocol, and know how to modify the bodies of the messages too. E.g. my router understands FTP, so FTP (in either active of passive mode) works fine even though there's a NAT in the way. The other possibility is that the NAT-er /doesn't/ understand the protocol, in that case the application programmers will have to do the equivalent of NAT-ing themselves. Such cases are (as far as I know) rare. There is little reason to embed IP numbers and ports into the body of TCP/IP messages. The biggest exception that /I/ know of, is tunnelling TCP/IP connections over SSH, and similar. To be honest I don't know nearly enough about how that works to say more about it, nor to speculate on how it is managed without co-operation from the application programmers.
-- chris
Bond - 31 May 2005 15:39 GMT First of all, WOW!!! This was a great reply... thanks Chris for the valuable information. One question does come to mind when reading the two sections below:
> For example a packet from my machine might have source IP > aaa.bbb.ccc.ddd, and source port 3872 (randomly allocated when it attempts to [quoted text clipped - 3 lines] > and has been assigned to me, and any machine anywhere on the network can > address my machine using that address.
> When it sees a packet emanating from my laptop (or anywhere else in the NAT-ed > subnet that it manages), it changes that packet so that it appears to come from its [quoted text clipped - 6 lines] > that my machine originally used. It changes the incoming packet to use that > destination IP/port and sends the packet on to my machine. So for this example, the server is responding by sending the data to address aaa.bbb.ccc.ddd and source port 3872 which would be forwarded to the local machine from the router. How long is this port dedicated to forwarding to the local machine?
Owen Jacobson - 31 May 2005 20:50 GMT >> When it sees a packet emanating from my laptop (or anywhere else in the >> NAT-ed subnet that it manages), it changes that packet so that it [quoted text clipped - 6 lines] > the local machine from the router. How long is this port dedicated to > forwarding to the local machine? As long as the connection is open. When a well-implemented NAT router sees a FIN or RST packet, it allows TCP/IP connection teardown to complete and is then free to dispose of the entry mapping aaa.bbb.ccc.ddd 3872 to a local computer.
O
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 ...
|
|
|