I am learning inter-process communication. I want to create server that can listen to client distributed over actual local area network. I have IP address as well as symbolic name of those machines. I can implement sever and client on single machine but I don't know how to do same on different machines on network.
Can anyone direct me to appropriate resources or tell me how to do it ?
Thanks
It's the same. The only difference is that you need to use the server ip address instead of the local address when you connect the client socket.
Related
I'm planning on writing a relatively simple client-server socket program in Java, where the server will run on one machine and the client on another machine (both wired on the same network).
Link two computers with Socket in Java.
From the answer to the above question, I believe that I will need to port forward (not an issue as I know how), but this does, however, go against my intuition as I am under the impression that port forwarding would only be necessary if I needed to connect to a service/machine/whatever on my network from a remote machine (not on the network).
So my question is, do I need to port forward for communicating between two machines on a local network? If yes, why?
If the machines are in the same network, you don't need to configure port-forwarding. Even if the machines are in different networks, you don't need to configure port-forwarding, assuming those machines have routable IP addresses (and there is no firewall blocking that access).
Port-forwarding is only relevant when communicating to - for example - a home network that has a single IP address, where there are multiple machines on an internal network, and the local router that is visible to the internet needs to perform NAT (Network Address Translation) to map between the local network and the big bad internet. Port-forwarding makes sure that an internet visible port is forwarded to the IP address of a machine on the internal network.
What you do need to take into account is the possibility that local machine firewalls (e.g. Windows Defender) may block access without explicitly whitelisting the application and/or port.
I want to simply connect two machines on the same network via a TCP Server/Client socket connection.
Right now, I need the IPv4 address from the machine hosting the server in order to connect the client.
localhost works fine when I'm running the server and the client on the same computer, but that's not very useful.
Is there any way around having to manually punch in the IPv4 of the host computer?
Thanks, this will probably clear up a lot of confusion.
Use a broadcast to send all clients a message. (this could contain the servers IP but think about that! it could be a security issue)
There are good examples on sending broadcast messages with java
Broadcasting to Multiple Recipients
If you know the name of the hosts, then you can also pass these names in a config file and use getaddrinfo() to get the IP address of the host: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html . Since hostnames do not chnage frequently, this should provide good improvement as compared to manually punching the IP address.
I have spent some time learning about socket programming in Java and have managed to make a couple of simple apps that utilize sockets. (instant messenger, tic-tac-toe, basic things) For my programs I used a client-server relationship with ServerSocket and Socket classes. So far I have been testing all my games on the same machine, meaning the client and the server both run on the same machine and the socket ip I am using is 127.0.0.1. Now I want to make a LAN game using the same logic. One computer will be the server and another will be the client.
The thing I wanted to ask, and pardon me if this is a stupid question, I am not really educated about networks and whatnot, but under what conditions can I establish a socket connection between two machines. What I mean is, I run my socket server on one computer and I want the socket on another computer to connect using the first computer's ip. Say, for example my ip is "192.1.1.4" I want to be able to connect to that computer. Is it possible to establish a connection like this between just any two computers in the world? I know "lan" stands for "local area network" but I am quite ignorant on it beyond that. Sorry it it is a dumb question and I can clarify it if someone needs me to.
Basically, what criteria must be met on two machines for me to be able to establish a socket connection between them using a Java program?
You can make a TCP/IP connection between:
Two machines in the same LAN (private IP)
Two machines with public IP (internet)
A machine in a LAN and a machine with public IP provided that the connection is openned from the LAN to the public IP
You can't open a direct TCP/IP connection to a machine inside a LAN from outside the LAN, unless the gateway is configured to redirect the connections to a specific port to that machine.
On an internal network you do just what you said, client connects to server using server's ip address or hostname on the given port.
over the internet can be tricky because of firewalls and NAT. For example, your computer's ip address on the home network is probably somewhere along the lines of "192.168.0.xxx" - but if you go to: http://www.whatismyipaddress.com you'll see that your internet facing ip address is completely different. What you'll see is basically your router's IP address on the internet (WAN).
So basically, the server will have to setup port forwarding on their router for your game's port to his computer. Then he will have to provide the clients with his internet facing ip address for connection.
The main criterion for establishing a connection - ignoring a multitude of possible factors such as firewall configuration, etc. - is that the two machines are simply on the same network. You may be aware that an IP address starting with 192.168.. always refers to a computer on a local network, which is the situation you are asking about, so if you have two computers connected on a local network (e.g. via a router), and you know the IP address of each machine, then it really is as simple as that - you connect in the same manner you have been using up until now. In fact, the same applies on the internet - even if you have two machines set up on different sides of the world and you know their IP addresses (again, ignoring potentially more significant firewall issues), the process is exactly the same. This is precisely the reason that the internet has proved so scalable, as the process of locating a machine with a particular IP address is handled by the lower layers of the network stack.
tl;dr: It's the same as what you are doing already, just with the appropriate IP addresses.
you can use a public IP address and you don't have to change anything about your own address, this is handled by your router that connects to the internet. What you do have to consider is your firewall settings. The ports you are using in your socket should be added to your 'allowed' list. Normally "established" traffic is allowed by default. This means that you need to allow your incoming ports # serverside to go to your server.
i have a server socket. Now there are two clients from 2 different machines connected to this server, which is in another machine. Is there any way to list out the ip addresses of these 2 client machines connected to the server?
Not from the server socket itself. The only way would by to keep a reference to all Sockets created from connections that the server has accepted.
There may be other ways of identifing connections though, for example interrogating operating system's native networking APIs, but this depends on your OS and wouldn't be a good thing to put into a Java app.
This is what I'm planning to do. Suppose there are 2 machines A and B. I need to create an application by which machine A can send data to Machine B, using Java SE.
I know that to make a connection you need to create an object of serversocket class and use the accept() method as
In Machine B:
ServerSocket ss=new ServerSocket(12000);
while(true)
{
Socket s=ss.accept();
.
.
.
.
}
In Machine A:
Socket s=new Socket("<Machine B's IP Address>",12000);
.
.
.
.
Here's the problem.
Suppose if Machine B's IP address is assigned dynamically with DHCP, ie it can change each time the machine reboots.
Is there any way by which the Java Pgm in machine A can recognize the IP address of B without the user typing it manually???
Hoping that you the question is clear.
Waiting for replies!
Most DNS servers have a mechanism that allows the DHCP server to make dynamic updates to the local (internal) zone. If you have this feature at your disposal, then you can just use DNS names, and let the systems guys make sure that the DNS records are up-to-date with the DHCP leases.
A similar DNS-based approach could be accomplished on the wider internet using a DDNS service like dyndns.
If you can't use DNS, then you're stuck with a UDP broadcast-based approach. This is the same mechanism that protocols like DHCP, bonjour, and SMB use to find other computers on the local network without knowing their addresses; and this approach will only work in the same contexts where those technologies work (typically, only within the local network, and definitely not across the greater internet).
In java, you would accomplish UDP broadcast messaging via the DatagramSocket class.
Quoting the api docs:
UDP broadcasts sends are always enabled on a DatagramSocket. In order to receive broadcast packets a DatagramSocket should be bound to the wildcard address. In some implementations, broadcast packets may also be received when a DatagramSocket is bound to a more specific address.
Example:
DatagramSocket s = new DatagramSocket(null);
s.bind(new InetSocketAddress(8888));
Which is equivalent to:
DatagramSocket s = new DatagramSocket(8888);
Both cases will create a DatagramSocket able to receive broadcasts on UDP port 8888.\
If your two machines are located at disparate locations on the internet, and you can't use a DDNS service (like dyndns, mentioned above), then your best bet is to build a central registration server. This would be a simple server (could even be a web service) that runs at a known address on the internet. Each of your client machines would register with the central registration server, thus the central registration server would know the IP addresses of both machines. Then each machine could request the other's address via the central registration server. You'd have to put some thought into to security in order to protect against malicious "poisoning" of your registry, but otherwise, this would be fairly straight forward.
EDIT:
I just discovered JXTA. It's a set of tools for building java applications with peer-to-peer networking features. I don't have any direct experience with it, but it looks like it would accomplish what you're looking for (and probably save you a lot of work over having to build it all from scratch).
In fact, it looks like the subproject p2psockets does exactly what you want.
In Java you can compute the IP address of machine by host name, Here is the code
java.net.InetAddress inetAdd = java.net.InetAddress.getByName("www.ibm.com");
System.out.println("IP Address is : " + inetAdd.getHostAddress());
Use this code to get the changed IP address every time machine reboots