I'm running an application on a bunch of nodes in a class A network, but can only access them from my own system if I log into the only node in that network that also has a class B address.
However, the client portion (with the GUI and everything) can run only on my system, so I need some way of communicating with the class A network. The client (my system) attempts to set up a simple TCP socket to the server (at the edge of the internal network, with a ServerSocket), but gets a Connection Timed Out exception. Since only the SSH port 22 is open, someone recommended I use SSH tunneling to send packets from my system to the internal network.
After a bit of Googling, I see that the following allows you to set up an SSH tunnel, but how would I use this from within Java to set up the sockets and what not? Thanks!
ssh -L 2222:10.10.10.10:22 174.174.174.174
EDIT:
I have used JSch to set up port forwarding from my system to an internal node, but is there any way I can make it bidirectional without having to set up a separate tunnel on every internal node? (The nodes aren't using the same TCP connection to respond, but have set up new connections to my laptop's port 2222.)
SSL Tunnel works just like any other socket, you just need to connect to the local socket. In your case, it's,
Socket socket = new Socket("localhost", 2222);
OutputStream out = socket.getOutputStream();
The tunnel will actually make a connection to 10.10.10.10:22.
If you're asking how to programatically set up the forwarded ports, use JSch which supports port forwarding.
Related
In accordance to example in this link:
http://www.javatpoint.com/socket-programming
As i understand port no :6666 is an imaginary or raw port used to illustrate socket programming. I want to know how the PC knows that it has server with port 6666 after running both myClient.java and myServer.java.
Also I want to know while doing Real socket programming the myServer.java needs to be placed in real server location if not then where ? just want to understand where to initialize a serverSocket class object! In server side or in client side ?
Also how Operating system or PC(in general ) search for available ports ?
Your linked document is broken, nevertheless, let me explain a bit how the network sockets work.
A computer has multiple network interfaces. If you're running window you can check them by running ipconfig /all, on linux/osx with ifconfig. You'll see that you have a loopback interface with IP address 127.0.0.1. Also, by convenience it was decided to add a "name" to this loopback interface, and it'd be localhost. You can verify this in /etc/hosts file where a mapping between 127.0.0.1 and localhost exists.
Saying that, a computer can find a route to localhost on himself using the system kernel. This loopback interface is virtual, implemented in the operating system so no packets will go through your Ethernet interface or wifi card.
TCP and UDP are protocols used on top of IP to send data. TCP establishes a connection via the 3-way handshake and packet reception is acknowledged by the server. UDP is non-connection oriented, so a client will send packets to the ports and no acknowledges are sent. That's just a huge summary.
When you want to listen on a port, your application needs to actually tell it to the operating system and when the networking component of the OS receives some packets with the TCP.dst value equal to 6666 (in your case) it will send the payload to your application. The OS is responsible for acknowledging the packets and all the underlaying communication which is transparent from you.
As you might guess, the operating system can only bind the same port port to a single application. That's why if you start twice a web server, the second execution will fail.
You can check which ports are listening with netstat -l on a linux machine.
I am having a aws server(10.10.10.1) which will act as a CISCO Router and it will port forward to another aws server(10.10.10.2). Now I am connecting a server in ssh using the following command.
ssh -i server.pem ec2-user#10.10.10.1 -p 2222
Then it will connect to the Server 10.10.10.2.
Now I need to run a socket program there and I need a client(Which will run in local) program to connect that.
I tried in many ways but I am not able to connect that.
I am new in socket programming please help me to sort out.
Below Answer Result:
I have tried to connect through the SSH tunnel and the tunnel is working for the router and it is not going to the aws server
Please see my tunnel command,
ssh -i server.pem -L 9080:10.10.10.2:8090 ec2-user#10.10.10.1
I also ran a Socket server code in 10.10.10.2 and the client code in my local machine.
Please help me to sort it out
This is your layout
DEV ---ssh---> PIVOT ---ssh---> SERVER
There's an SSH feature called port forwarding that allows the user to open a listening (server) socket on one end of the connection (-L for local, -R for remote) and proxy all socket reads and writes to another machine reachable from that end.
Since PIVOT can connect to SERVER you simply need a proxy on your DEV machine:
me#dev$ ssh -L 9005:server:80 pivot
And then when you talk to localhost:9005 on the development machine you are in fact talking to server:80 via the SSH channel.
Note: if host A can't directly connect to the server and you use it to ssh into B that can, you actually have to setup two forwards, one for each SSH bridge.
I have 2 DIY Gears running simple a Java Client-Server Application with Sockets.
What I want to do is sent a command via Socket to Gear1, which sends a command via Socket to Gear2, then sends back to the user whatever data Gear2 sent back.
The problem is that I can't connect to Gear2 from Gear1.
Gear1 address = 127.13.55.1:16000
Gear2 address = 127.7.21.129:16001
I forwarded port 16000 on Gear1 so that I can communicate with it from a local client. But when I try to connect to Gear2 from inside Gear1 I get the error message: java.net.NoRouteToHostException: No route to host.
Is there some configuration I forgot about?
The two gears will not be able to communicate with each other on those ports. Inter-gear communication is blocked on non standard ports, except in special cases with scaled applications. You would have to use port forwarding between the gears for this to work, the same as you do from your local machine.
I am trying to create a java chat application for my networking class. As of right now I am stuck trying to connect to someone behind a different router. The way I have my project right now is I have a client program and a server program. The client programs first logs into the server program which logs their IP and port in a database and then the server gives them back the list of their friends with their IPs and ports. Then the client closes down the connection to the server and tries to connect to another client using the information the server sent back. So far my program only works connecting to the server and getting the friends IP and port but when I use those values to connect to the other client I cant connect.
socket = new Socket();
socket.setReuseAddress(true);
socket.setKeepAlive(true);
socket.setSoLinger(true, 10);
socket.bind(new InetSocketAddress(Port));
socket.connect(new InetSocketAddress(host, SERVER_PORT));
reusePort = socket.getLocalPort();
Above is a snippet of java code used to connect to the server then below is what i do on the client side.
ss = new ServerSocket(reusePort);
So now technically I am listening on the same port I used to connect to the server with which is logged in and is retrievable to another client and is in the NAT table with my ip and port. I am not sure what I am missing or if there is some protocol or something that I have to do. I have looked at TCP and UDP hole punching but I am not sure how that is actually accomplished or how to implement it.
Any suggestions would be appreciated.
If you want to send a message you'll need to set up port forwarding on any device that acts as a server (any device which creates a socket server). Port forwarding is done on the Router. The reason you cannot connect to the other client is because they are hidden behind their routers firewall. Their address to the rest of the world is actually the address of the router, not of their physical computer. On their local network they have a different address then what the rest of the world sees, and the router figures out what messages from the outside world need to be sent to the client based on an address translation table.
Given your architecture, this would mean that all clients need to have their routers doing port forwarding, which is of course unfeasible (imagine gtalk or aim requiring users to do port forwarding).
The more common architecture is to have the Server do the work of rebroadcasting messages to the connected clients and maintain tables to lookup whose talking with who. This way there is a single server which will need a static ip (or be port forwarded), and all users are simply clients which connect to the server socket and read messages from it.
For actual code describing the second architecture please see http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Then the machine which is running the server code either needs a static ip or if it is behind a router needs traffic from the port it is listening on to be forwarded.
So on the server code you will bind to the ip assigned from your router (something like 192.168.1.2 at some port say 5000). Then go to your routers configuration page (it may be 192.168.1.1 see http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router), and forward port 5000 to the address 192.168.1.2.
The Interactive Connectivity Establishment (ICE) protocol combines various NAT traversal utilities such as the STUN and TURN protocols in order to offer a powerful mechanism that allows Offer/Answer based protocols such as SIP and XMPP to traverse NATs.
This project provides a Java implementation of the ICE protocol that would be usable by both SIP and XMPP applications. The project also provides features such as socket sharing and support for Pseudo TCP.
ice4j is maintained by the Jitsi community.
ice4j
I am creating socket using socket = new Socket(host, port, InetAddress.getLocalHost(), clientPort);. I want the socket to listen to particular port at client side. But when I use InetAddress.getLocalHost() I get java.net.ConnectException: connect: Address is invalid on local machine, or port is not valid on remote machine.
But when I use InetAddress.getByName("localhost") it works fine. But I require IP address of the machine in server side. So when I use socket.getInetAddress() I want ipadress and not 127.0.0.1.
Can anyone please help.
I am using eclipse. Can this be a firewall issue?
Thanks
You're using the four-argument form of the Socket constructor (really unusual; it's normal to only use the two argument form and let the OS figure out the local address side for itself) so you need to make sure that the two addresses associated with the socket are compatible, i.e., that it is possible to route packets that way. In particular, if either end is localhost, the other end must be too because that address is only ever routed over the loopback network interface.
The simplest fix for you (on the client side) is going to be to switch to using the two-argument constructor, leaving the OS to figure out the rest of it for you; it does a good job. (If the server depends on the client connection coming from a specific port number, that's awful and terribly terribly fragile.)
Sounds like confusion over client-side and server-side responsibilities - sounds like you're trying to get two Java applications talking to each other on the same host via TCP/IP, using Java Sockets.
If this is the case you first need to use a ServerSocket in the 'server' application to create a listening socket on all interfaces:
serverSocket = new ServerSocket(4444);
You should then be able to connect to the ServerSocket from the 'client' application by using a Socket to connect to the localhost:
clientSocket = new Socket("localhost", 4444);
The following page(s) looks like they cover this in detail:
All About Sockets
Hope that helps.