I have a Java backend program and multiple instances of it are run on the server. The instances listen on various ports through TCP socket connections from clients. I want the client applications to connect to a single port and a program on that port should load balance between the multiple instances.
I also want to be able to update the backend instances (stop and re-run) individually during a software update, so that there is at least one running and available port for the clients to connect to. How should I go about doing this? Does Java already have an in-built feature to perform this? If not, is there a free or low-cost program/API that can do this? I don't have a lot of budget and will not be able to purchase expensive APIs or pay for something like AWS.
Related
The problem: In java you can create a socket on the server with ServerSocket(0) and it will choose a random port to listen on. However when you create a socket on the client to send a message with Socket(addr, port) there is no apparent way to determine which port on the server you need to send to. I couldn't find anything about this option through web searches besides the basic "if you put 0 it will chose a random port". Does anyone know or have a resource that could explain what this scenario is supposed to look like from the client end?
Some background: I am currently converting a system from UDP to TCP. The reason I need the server to listen on a random port is that my server/client do not have a strict server/client relationship. So the "server" in this situation is really an application that I need to open multiple instances of on one PC. The old way of having predetermined send/receive ports is causing only one instance to be able to open a port and all communication is being redirected to that instance. My understanding that the best way to fix this problem is for each instance to use a different port, and the best way for that is to do ServerSocket(0). Despite including this background, I do not want comments on how messed up the situation is, only answers pertaining to the problem.
If a fixed port number is not part of the server's documented setup / protocol, then the only way for clients to figure out is to have the running/active servers publish that information in some datastore, the location and details of which are documented and known by the clients, and where that datastore is reachable for the clients.
[Or have the clients run a portscan each time they want to connect. It will work but probably not as fast as your users would like.]
And your situation is indeed messed up.
Perhaps if you are on the same IP subnet with all the servers/clients, then you could use UPnP to signal which random port new instances of your application are running on, and similarly other instances could monitor UPnP to discover this new instance.
I've never implemented UPnP in Java, but suspect libraries are out there..
eg. https://github.com/jupnp/jupnp
Let's say, within a program, there are capabilities to connect to a socket and server(which would be my own computer - localhost) and has all the handling for communicating to the server and back (receiving and sending messages like a chat service). If i send this program as a .jar file to two other users their respective machines, as the users executes the program, it would connect to this socket and server. If all was set up correctly (correctly writes and reads from the socket inputstream and outputstreams) and displays the messages on a GUI chat box, would the two users be able to communicate with this chat service?
Yes, but the main barrier that would prevent users from doing this is a little something called Network Address Translation (NAT).
In short, the vast majority of computers connected to the Internet do not have their own, unique, public IPv4 address (and the vast majority do not have IPv6 addresses either, because ISPs are dragging their feet in rolling out IPv6, but that's another matter entirely).
Dedicated servers often do have (usually multiple) unique IPv4 addresses, but significant numbers of IP addresses are usually only available to hosting companies that operate their own Autonomous System -- and even then, purchasing IPs these days is very expensive, because they're a valuable and rare commodity.
Anyway, two random users on some sort of home Internet connection (like cable, DSL, or fiber) almost certainly have a router or modem of some sort that performs NAT, giving each user device (computer, tablet, etc.) their own private LAN IP, instead of giving each device a unique public IP.
This means that inbound connections from the public Internet are, by default, ignored by the NAT gateway. So if you try to open a socket to your friend's public IP, unless that gateway (modem/router) has been configured correctly, it will just silently ignore your connection attempt, and you'll get a timeout or "connection refused" type message.
There are a few techniques for getting around this, but most of them either require much more complicated application network code, or require the user to mess around in their router configuration pages (which casual users usually aren't willing to do).
Port forwarding: Users must manually configure their router to "forward" public IP ports to a specific private IP, thus allowing the connection attempt on the public IP to pass through the Network Address Translation table to the private LAN. There is no general-purpose way of automating this without user intervention due to the differences between router/gateway devices.
NAT Traversal, which requires one of a variety of NAT-T protocols to be implemented in your program, and requires the explicit support of the desired NAT-T protocol for the routers involved (yours and your friend's). There are loads of different NAT-T protocols available; it'd be up to you to determine which one to use, based on compatibility, availability, etc.
Using an interposing server as an indirect way of routing packets between the two: In this case, you create a server on the public Internet that does have a unique IP (or has ports forwarded to it), and have each of your two client computers initiate an outbound connection to that server. The server would accept connections from both clients, then process the packets and pass them along, like talking to someone through a middleman. This doesn't require any special configuration on the clients, as long as they can make outbound connections on the desired ports (by default, most can, except in restricted enterprise environments where your ports may be limited to a few like 80 and 443.)
You'd need to adopt one of these techniques if your clients are using NAT. If one of your clients has a static IP directly connected to their computer and can accept incoming connections directly (without NAT), your program concept would work without modification, as long as the user behind the NAT initiates the connection to the one with a static IP.
I want to simulate running of multiple servers and clients on a single machine.
I plan to create multiple threads of servers and clients using Java's concurrency package.
I will differentiate between servers and clients from each other and among them using only port numbers.
Say, I will have a series of 800XX ports for servers and 900XX ports for clients.
I need to know if what I am doing is correct. Is there a better way of doing it?
Your idea is correct. One minor comment is that the client ports can be automatically allocated by system.
I have a application which listens for commands over IP.
The program works fine locally but when I try to send the application commands with a remote address it won't connect.
Is there anyway to get around the router blocking the inbound network traffic?
I'm using JAVA
Thanks.
If this is a pair of hosts you control, you can open the incoming port. You might also
succeed using a tunneling program such as Hamachi to effectively set up a VPN linking
the hosts.
If you're talking about a pair of unrelated computers (for example trying to set up
a connection for a game) there's no general solution that doesn't involve installing
and trusting additional software. The usual solution is to use a public server and
relay the traffic between the end points.
I created a game and I want to put it on online. I want to buy a website (I'll probably use goddaddy to buy a domain name and use them as the web host) to use as the server to handle game play. Because I would need a separate server for each game, I would need each game's server to exists on different ports. So this leads to my question, is is possible to access these ports on my future web server? (I wrote the program in Java, so I would assume that I would access the ports from the server side by choosing a port for a ServerSocket, and from the client side by using the IP address from the website and the chosen port for a Socket)
(note: also, I am aware that it may be easier to simply use one port and run the servers on different threads instead, but I am just curious to have my question answered)
thanks a lot,
Ian
Technically it is possible to use different ports, but I don't think that a webhoster like goddaddy will let you run a java process that binds to a special port.
If you mean that you are going to create your own TCP server you obviously can create as many instances of your server and configure them to listen to different ports. But it is year 2011 now. This solution was OK in early 90s.
I'd suggest you to use Restful API that works over HTTP. In this case you can forward calls to server side of each application using URL, e.g.
http://www.lan.com/foo/login?user=u123&password=123456 - log in into application foo
http://www.lan.com/bar/login?user=u123&password=123456 - log in into application bar
In this case you need only one server (the web server) that is listening to socket (port 80).
Your server side implementation could be done using various web techonlogis (php, java, asp.net etc) on your choice.
Yes, that should work. The security manager permits connections to a different port on the same IP address that the applet was loaded from.
You can run a Java server on whatever port you want. Each server will accept incoming requests on one port.
The correct way is simply run on one port and each connection will instantiate a new servlet instance (which happens to run in its own thread) that can then service that request. You usually don't need to run separate ports or worry about concurrency, especially if all the stuff that's shared between connections (e.g. multiple players in one game) is handled through database read/writes.
Your host (GoDaddy) will have to allow you use of those ports, but if they are providing proper hosting (not virtual hosting) and given you your own IP there's no reason why you shouldn't be able to.
Your solution may work theoritically, and I like AlexR's solution. But providers like godaddy doesnt let you run a java server, on ANY port. You will need to find out somebody who does. What I found is the cost goes up from $5/mo to about $20/mo, but you get a much better (read faster) machine. Good wishes, - MS.