Accept all incoming requests on a ServerSocket - java

I'm temporarily using the following line to create a ServerSocket on my Android phone:
socketl = new ServerSocket(port, 0, InetAddress.getByName("192.168.0.108"));
But it's really annoying and, besides, not user-friendly to change the IP address manually every time the DHCP assigns a new IP to the phone. So I'm searching for a way to get the IP-Address the DHCP-Server gave to my phone.
Ive tries InetAddress.getLocalHost().getHostAddress(), but that only returned the IPv4 loopback (127.0.0.1).
Is there a way to either get the current local IP(v4) or a way to accept every request, no matter which IP is used to connected? If the IP-Address in the line above isn't the same as the one the client uses, it doesn't work.

You could use
socketl = new ServerSocket(port, 0);
or even
socketl = new ServerSocket(port);

Related

TCP socket connection over internet

I am doing a project for which connection between server and client is required.
I did it by adding TCP sockets.
Here is the code fraction :
Server:
ServerSocket welcomeSocket = new ServerSocket(80);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
WorkerThread wt = new WorkerThread(connectionSocket, id);
Thread t = new Thread(wt);
t.start();
workerThreadCount++;
}
Client :
Socket skt = new Socket("192.168.0.108", 80); // The IP address is from cmd->ipconfig/all-> IPv4 Address
outToServer = new PrintWriter(skt.getOutputStream(), true);
inFromServer = new BufferedReader(new InputStreamReader(skt.getInputStream()));
It all works when both ends are in same device/under same WiFi.But I don't understand what to do for creating connection over internet.
Please help with clear steps.
Here:
Socket skt = new Socket("192.168.0.108", 80);
That is local address. If you want to have a server that is reachable on the internet, then that server needs to have its global public IP address!
In other words: you have to make sure that the server can be reached from the internet somehow. For example by turning to some service provider that hosts servers that you can then equip with your code!
The whole purpose of 192.168 addresses is to be defined only in a local subnet.
Alternatively, you have to check if your ISP has a service where the ISP assigns an IP address to your connection, and that allows calls from the internet to go to your "place".
Meaning: when you want to receive phone calls, you need a phone that is connected to the phone net!
In order to connect to a socket over WAN, you must port forward that port to your local device. This can be done in your routers' settings.
192.168.0.108 --> That's your local IP-address.
This can be used on your local network without any requirements for port forwarding whatsoever. However, to use it over WAN, execute the following steps:
Step 1: Search for your routers' model number and port forwarding on Google on how-to forward port 80 to your local IP-address. Warning: use a static IP-address on your local device to prevent your IP from changing after a reboot.
Step 2: Go to a website like IP Chicken and find your external IP-address.
You can then connect to your socket using:
Socket skt = new Socket("[EXTERNALIP]", 80);
Please be noticed: unless you have a business network, your external IP-address will probably change from time to time.

Java multiple multicast sockets in same group on same host and port

I'm using multicast to implement a simple discovery service. Several instances on the application must be able to run on the same host, I therefore end up with several multicast sockets that are members of the same group on the same host.
On Linux, this works as expected. Every instance of the application on a host receives the messages sent to the multicast address.
On Windows however, only the first application to join the multicast group receives the messages sent.
Here is the code I'm using to create my multicast socket:
socket = new MulticastSocket(PORT);
InetAddress group = InetAddress.getByName(ADDRESS);
socket.joinGroup(group);
socket.setTimeToLive(TTL);
Is there some option I need to set? I've tried scouring the API but I can't find anything.
EDIT: According to this website, I need to set SO_REUSEADDR, but this can only be set before the socket binds. It seems the constructor for MulticastSocket seems to bind the socket upon creation.
you do this by creating the socket with no arguments and then call bind on that object.
socket = new MulticastSocket();
socket.setReuseAddress(true);//redundant, already set with empty constructor
SocketAddress sockAddr = new InetSocketAddress(PORT);
socket.bind(sockAddr);
InetAddress group = InetAddress.getByName(ADDRESS);
socket.joinGroup(group);
socket.setTimeToLive(TTL);

DatagramSocket Broadcast Behavior (Windows vs. Linux)

Backstory:
I have a wireless device which creates it's own SSID, assigns itself an IP address using auto-ip, and begins broadcasting discovery information to 255.255.255.255. (unfortunately, it does not easily support multicast)
What I'm trying to do:
I need to be able to receive the discovery information, then send configuration information to the device. The problem is, with auto-ip, the "IP negotiation" process can take minutes on Windows, etc (during which time I can see the broadcasts and can even send broadcast information back to the device).
So I enumerate all connected network interfaces (can't directly tell which will be used to talk to the device), create a DatagramSocket for each of their addresses, then start listening. If I receive the discovery information via a particular socket, I know I can use that same socket to send data back to the device. This works on Windows.
The problem:
On Linux and OSX, the following code does not receive broadcast packets:
byte[] addr = {(byte)169, (byte)254, (byte)6, (byte)215};
DatagramSocket foo = new DatagramSocket(new InetSocketAddress(InetAddress.getByAddress(addr), PORT_NUM));
while (true)
{
byte[] buf = new byte[256];
DatagramPacket pct = new DatagramPacket(buf, buf.length);
foo.receive(pct);
System.out.println( IoBuffer.wrap(buf).getHexDump() );
}
In order to receive broadcast packets (on Linux/OSX), I need to create my DatagramSocket using:
DatagramSocket foo = new DatagramSocket(PORT_NUM);
However, when I then use this socket to send data back to the device, the packet is routed by the OS (I'm assuming) and since the interface of interest may be in the middle of auto-ip negotiation, fails.
Thoughts on the following?
How to get the "working" Windows behavior to happen on Linux/OSX
A better way to handle this process
Thanks in advance!
I do not think this is the problem with the code. Have you checked if OSX/Linux has correctly allowed those address / port number through their firewalls? I had this simple problem too in the past =P..
FYI, there is a nice technology called Zero-configuration which was built to solve this problem. It is very easy to learn so I recommend you to having a look at that as well.
Good luck.

Remotely connecting two non-local computers with sockets

This question seems like something very obvious to ask, and yet I spent more than an hour trying to find an answer.
First I host and wait for someone to connect. Then, from another instance of the application, I try to connect with a socket - for the constructor, I use InetAddress, port. The port is always right, and everything works if I use "localhost" for the address. However, if I type my IP (the one I got from Googling "what is my ip"), I get an IOException. I even sent the application to someone else, gave him my IP, and it didn't work.
The aim of the application is to connect two computers. It's in Java. Here is the relevant code.
Server:
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();
Client:
InetAddress a = InetAddress.getByName(ip);
Socket s = new Socket(a, port);
I don't get past that. Obviously, the values of int port and String ip are taken from text fields.
Edit: the purpose of my application is to connect two non-local computers.
As mentionned by Greg Hewgill, if you are behind a NAT Device (Router, etc...) you will have to do some Port Forwarding.
Basically, your public IP Address that you get from using "What is my IP" from google is your public IP Address, but since you are using a router with multiple computers connected to it, there is a protocol that maps multiple computers to a single public address called NAT.
What you'll need to do is tell your router to forward the incoming packets on a certain port to a certain computer.
The way to do this is highlighted in this article http://www.wikihow.com/Port-Forward

How to send request from virtual IP address to a server?

Can any one tell me how could i send request to a server using different IP address. Let me explain the requirement; I have to create n no of different virtual IP address in my machine, and then I have to sent request to a different server using those individual virtual IP address. Like one request from one virtual IP address , one from another virtual IP address. Can anyone tell me how could I achieve this programatically ? I am developing my code in java so if you have any code or concept on this please share with me.
It's done the same way in Java as any other language: you bind the socket to the address you want to connect from, before you connect.
Socket s = new Socket();
/*
* Change the 192.168.0.1 to whatever IP address you want the connection
* to come from. If your IP address is stored in an InetAddress object,
* you can use that too, instead of a string.
*/
SocketAddress from = new InetSocketAddress("192.168.0.1", 0);
SocketAddress to = new InetSocketAddress("192.168.0.2", 80);
s.bind(from);
s.connect(to);

Categories

Resources