I have a serversocket running on a port say 7761 in my server with ip say 10.2.110.43
now there are many client that run on different servers waiting for connection on port 7761, and write data in ascii format to that port.
I want the serversocket to verify the client-ipadress and then accept connection from client.
Is there a way to do that?
If you don't mind running under a SecurityManager and the list of IP addresses is static, you can accomplish this via the security.policy file. Just grant SocketPermission"accept" to only those IP addresses you want to accept connections from. However doing it in code or the firewall as suggested in another answers is probably preferable.
We see in the following code, we can't check address of counterparts before accept() but after:
Socket client = serverSocket.accept()
if( acceptedClients.contains( client.getInetAddress()) {
...
}
else {
client.close();
}
With acceptedClients a collection of well known InetAddress.
If you don't want the connection to reach your Java ServerSocket#accept() unless it comes from a specific IP, you will have to configure your firewall to do this.
You can always validate the IP address after the connection is established and immediately close it if it's not from the right IP.
Related
When we send data (in this case) to a client/server, does this really matter to use the same port number?
My guess is no, because it doesn't matter which port you are using when sending data to. (The protocol gives it to you randomly internally - this is the idea?) The only thing has to be kept, the port has to be any availabe one on the receiver machine(above 1000, because those are reserverd by the system), and if that receiver decides to send something back, he or she will have enough information about sender: his IP address, port number ect. As far as i know, a received packed provides with all of that info.
Below is just an illustration of what i've said above.
public class Server {
public static void main(String[] args) {
GameServer server = new GameSever(9822);
server.start();
InetAddress address = null;
int port = 7877;
try {
address = InetAddress.getByName("192.168.0.2");
} catch (UnknownHostException e) {
e.printStackTrace();
}
server.send(new byte[] { 1, 2, 3 }, address, port);
}
}
When a server listens on a computer, it specifies a port it wants it's connections coming in from , so ports are important for setting up servers. This is useful as you can have multiple applications listening on different ports without the different applications accidentally talking to eachother. So you should decide on a port that isn't a standard( 80 is for HTTP for example) to exclusively use for you gameserver so the client knows which port to send the requests to.
If you want to handle multiple connections at once the best thing to do is threading.
When we send data (in this case) to a client/server, does this really
matter to use the same port number? My guess is no, because it doesn't
matter which port you are using when sending data to.
Firstly, use the terms client and server distinguishly(as generally client initiates by sending the message, to which the server responds).
Next, the port which you're using is logically of no significance, the reason being server uses request.getPort() to determine the port while seding the response; (request is a DatagramPacket sent by the client).
Though you can hardcode the port at server(if known beforehand), but, it is a bad idea. What in those applications where you've no idea about who sent the datagram packet?
Java documentation by Oracle also uses an example of client-server where client's port number is left for the constructor to pick. It mentions :
Mostly, the client uses a constructor that does not require a port number. This constructor just binds the DatagramSocket to any available local port.
It doesn't matter what port the client is bound to because the DatagramPackets contain the addressing information. The server gets the port number from the DatagramPackets and send its response to that port.
MORE INFO (taken from Java Network Programming) :
public DatagramSocket() throws SocketException
This constructor creates a socket that is bound to an anonymous port. For example:
DatagramSocket client = new DatagramSocket();
Pick this constructor for a client that initiates a conversation with a server. In this scenario, you don’t care what port the socket is bound to because the server will send its response to the port from which the datagram originated. Letting the system assign a port means that you don’t have to worry about finding an unused port. If, for some reason, you need to know the local port, you can find out with the getLocalPort() method.
NOTE : The same socket can receive the datagrams that a server sends back to it(underlying implementation).
Whereas, the below constructor creates a socket that listens for incoming datagrams on a particular port, specified by the port argument :
public DatagramSocket(int port) throws SocketException
Use this constructor to write a server that listens on a well-known port.
Short answer:
Your guess is correct.
Longer answer:
Client gets a random port number when sending data to a server and each packet has a header which contains the info about client's port, ip address ect. So server can easily retreive this information and send anything back.
Whereas the server needs to be bind to a specific port in order to clients be able to send data to that server because when you use UDP, you need to specify an IP address and a port.
I want to let the user have the freedom to choose a specific local address to connect to the target server since there might be customized routing policies, but want the program to pick up an ephemeral port instead of specifying one since that may need manual-test of local port availability.
I checked the constructors of "Socket" and "InetSocketAddress", it seems none of them have one to do the above task (even though it can pick up a local address and an ephemeral port simultaneously), and there is no method to do so after the initialization.
There is a construtor
public Socket(InetAddress address,
int port,
InetAddress localAddr,
int localPort)
throws IOException
that should be suitable for your requirement. If localPort is 0, the system will pick a free port.
You can create a Socket and call connect on it later.
Socket socket = new Socket(); // no idea where to connect
socket.connect(addressAndPort); // now I know.
What I do is have a TCPRegistry for testing purposes. This component takes care of aliased ports. e.g. host.port1. It gives it an ephemeral port on the server and allows the client to connect to it using the same string.
Note: to allow the client to start before the server I can ask it to pre-build these ServerSocket in the unit test.
Finally, at the end of the test, I can either check all Sockets and ServerSockets were closed, or forcefully clean them up.
It is designed for NIO, but could be adapted for plain IO TCPRegistry
My ServerSocket listens to LAN Connections and accepts them well, but when I try to connect to the same through my Phone - using the 3G connection - it doesn't seem to connect.
I tried using getMyIP site to get the IP and try to connect to it, it does get the right IP (checked with my router) but then no connections are accepted at all.
I tried opening the port on windows 7 and on my router altogether.
I put those lines in my Server constructor:
ss = new ServerSocket(port);
host=ss.getInetAddress().getHostAddress();
and I get the ip on host to 0.0.0.0
Thanks for your help.
- While you are at LAN, you can use the Private IP as well as Public IP ranges
- But when you are using the Internet to access the Server which is at your place, then you need to have a static Public IP address.
- You can ask for a static Public IP address from your ISP at some extra cost, there are also some site over net that some how provides a static IP on the basis of your Dynamic IP.
Private IP ranges Can't be used over the Internet.
Class A - 10.0.0.0 - 10.255.255.255
Class B - 172.16.0.0 - 172.31.255.255
Class C - 192.168.0.0 - 192.168.255.255
You need to have a public IP address. If you have a router it must pass traffic for the port you want to expose to the internet to your machine. If you have a firewall, it must allow external connections to this port.
All the changes you do are the same regardless of language you use and there is nothing you can do from Java to work around needing to do these things.
Check your firewall if it allows incoming connection. You need to make and exception there.
you need to bind explicitly the IP address on your machine which is allocated for that instance of time by your ISP.
You can get the IP address allocated to you by running ipconfig command on windows command prompt.
Use the following code to bind to a specific IP address
InetSocketAddress insa = new InetSocketAddress("22.23.23.111", 9090);
ServerSocket ss = new ServerSocket();
ss.bind(insa);
String host=ss.getInetAddress().getHostAddress();
System.out.println(host);
This prints the IP address allocated to you.
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
I am going through Sun's Java tutorial. I am in the lesson about sockets. There is the following code for a simple threaded server:
import java.net.*;
import java.io.*;
public class KKMultiServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
while (listening)
new KKMultiServerThread(serverSocket.accept()).start();
serverSocket.close();
}
}
The server is said to "keep listening for more incoming connections". I just don't understand how it's possible; the line serverSocket.accept() constructs a new (client) Socket object which is, according to the tutorial "bound to the same local port and has its...". Well, how is it possible that the server is communicating with the client and listening to more incoming connections on the same port? As far as I know, if a port is used for some connection it is blocked and cannot be used for more things.
So what am I getting wrong here?
Well, a socket is not one-to-one based on a port, it is unique on a tuple of (address, port). A connection - the pair of the local and remote sockets involved in the communication - is used to demux incoming data from a port to the correct socket, allowing multiple sockets on one port. See Wikipedia. In other words, the relationship of sockets to ports are N-to-1
getting multiple connections on the same port is entirely possible as each TCP connection is a (local host, local port, remote host, remote port) tuple as long as at least 1 is different the connections are distinct and won't interfere (besides bandwidth drops)
clients attempting to connect to a server generally get a port assigned from the OS that is not used currently
Listening sockets work like a receptionist in on a business's phone switch. Everyone calls the switch number, and the receptionist responds to each incoming call on the switch line by having someone else handle the call on another line. Even though the receptionist can only take one call at a time, the switch line is tied up only very briefly because it is used only to establish a connection.
[...]TCP demultiplexes incoming segments using all four values that comprise the local and foreign addresses: destination IP address, destination port number, source IP address, and source port number. TCP cannot determine which process gets an incoming segment by looking at the destination port only. Also, the only one of the [various] endpoints at [a given port number] that will receive incoming connection requests is the one in the listen state. (p255, TCP-IP Illustrated Volume 1, W. Richard Stevens)
The last sentence in the above quote is the key to understanding.
Interestingly, a socket isn't really identified by the combination of IP address and port. This is unique only in context, where the context is either a particular connection or the listening state. Only one listener socket can bind to a particular IP/port combination.
The short and sweet answer is that the port is blocked for OTHER programs and processes. Only the program that opened the port can now listen on it. BUT it can listen to many different clients on the same port.
When a client connects, it creates a unique socket. A socket is comprised of the listening IP address and port (the one you opened) AND the calling IP address and port. Because the caller's IP address and port are always unique, each socket is unique and identifiable to your listener.
Even if I connected to your program twice from the same machine, my machine would select a new and random source port for each connection -- thus ensuring that we have a unique socket each time.
Based on this link
The accept method waits until a client starts up and requests a connection on the host and port of this server (in this example, the server is running on the hypothetical machine taranis on port 4444). When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to the same local port and has its remote address and remote port set to that of the client.The server can communicate with the client over this new Socket and continue to listen for client connection requests on the original ServerSocket This particular version of the program doesn't listen for more client connection requests.
Here is SO discussion which may clear confusion about how single port handles multiple client calls Port and Socket SO discussion .
To put it in simple terms, most of the webservers listen on port 8080 and multiple clients will access same port to access your website.