Java Socket... how it works? - java

I have a question on Java sockets.
I'm trying to build a basic server-client connection in java using the net package classes. so to start with, I'm used the Socket class and created a socket attached to what will be the client using
address= InetAddress.getByName(ip);
socket = new Socket(address , port );
ip: is just a string representation of the ip address and port is a port number I specified to attach the socket to.
Now my question is, when I use the method getLocalPort() I get a different port number than the one I specified.Also, when I use the command 'netstat' on the command prompt I don't find the port number at which the socket is connected to in the list of active connections.
can anybody explain why is that?

port is a port number I specified to attach the socket to
No it isn't. It is the remote port number to connect the socket to. One of the problems in your question is that you are using terminology incorrectly and therefore confusing yourself.
when I use the method getLocalPort() I get a different port number than the one I specified.
No you didn't. You specified the remote port when creating the Socket. getLocalPort() returns the local port. They aren't the same thing. There is a way to specify a local port number as well, but you don't need it. That process is calling 'binding'. Neither 'bind' nor 'connect' is an 'attach'.
Also, when I use the command 'netstat' on the command prompt I don't find the port number at which the socket is connected to in the list of active connections.
You should. You should see a line with the remote IP:port in the remote column, and the state as ESTABLISHED.

That's because the port number you specify in new Socket(address , port ); is the remote port number. For example, if your remote server had a socket open on port 8123 you wanted to connect to, you'd enter new Socket(address , 8123);.
The port number you're seeing in getLocalPort() and in netstat is the port number auto-generated for your local machine socket.

Related

Open socket server to clients outside of localhost

TLDR: Allow people not on localhost connect to my chat server if they have the server IP.
I am starting to learn about socket programming in Java and I have come across an issue that I can't seem to figure out. I have created a basic chat program with a server and a client using sockets. This works perfectly in localhost, but I want to share it with my friends. I have searched for hours and can't really find a solution. From what I've read I need to bind my ServerSocket with my IP or Port forward. Just looking for some clarification and possible steps I could take.
How I'm starting the server
ServerSocket server = new ServerSocket(5056);
How I'm connecting to the server
Scanner readIp = new Scanner(System.in);
String ip = readIp.nextLine();
socket = new Socket(InetAddress.getByName(ip), Integer.parseInt("5056"));
Posts I've looked at
Java Socket port forwarding
https://coderanch.com/t/571967/java/connect-machine-localhost
What does it mean to bind() a socket to any address other than localhost?
To 'Allow people not on localhost connect to my chat server if they have the server IP.' and outside of your LAN:
public 'white' external IP.
So for example this page https://whatismyipaddress.com/ should display exactly same IP address as displayed in your OS
non blocked incoming connections on ISP level: your ISP should allow incoming connections to your computer from internet.
some opened port, not blocked by local firewall or by ISP.
Typically all ports below 1024 are blocked for input on ISP level.
No presence of NAT ( exclusions are present but outside of this topic ), thats common for WiFi/3/4/5g home routers.
As you may already understood - thats complicated.
So faster will be to use an external service,like https://portmap.io/ :
it does VPN connection + port forwarding, so knocking on their server from internet will actually call your local chat server.

Stop server in eclipse project

I am developing a client server application in eclipse where the client and server connect through port 4444 to send numbers to eachother. However I am getting this error message
Address already in use: JVM_Bind
Does this mean that the port is in use? Can anyone advise me on how to fix this error?
Only one ServerSocket can bind a SocketAddress (IP address and port number).
Possible reasons why the address is already bound:
Another application on your system currently uses this port (in this case: pick another port)
You may still have a running instance of your application in the background (in this case: terminate it in the console view in Eclipse)
You attempted to bind the SocketAddress twice (in this case: fix your program).
I believe port 4444 is blocked on some routers by default. Running the command netstat -a in cmd should give you a list of all ports in use. Try using a different port if possible.

Java Servlet Returns Remote Port of 0?

I'm using a servlet deployed on Google AppEngine to respond with the client's remote port number. HttpServletRequest.getRemoteAddr() works fine, but getRemotePort() returns 0?
Port 0 isn't valid. I've tried other IP services that told me normal port numbers (i.e. 55046 or something) but my servlet returns 0 every time it is accessed from a browser or from Java code.
My end goal is being able to tell a connection initiator upon lookup the recipient's address and external port location so a TCP hole punching technique will work properly.
What is the reason for this? How can I get the actual port number (if possible)? Does a NAT router not use a proxy port?
I'm not sure why getRemotePort would return 0, but for your end goal knowing the client port is useless. The client port gets reassigned for every connection. In fact, if the first connection uses 55046, the whole point of the client port is for a new connection to use a different, and unused client port number.
This makes it useless information for configuring a hole in the firewall policy. You will not need the client port. What you need is the server port, the server address, and optionally the client address if you only want to allow access from that client address.

Java TCP socket: java.net.ConnectException: connect: Address is invalid on local machine, or port is not valid on remote machine

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.

Communication between two nodes running Java apps using SSH tunnel

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.

Categories

Resources