JavaME, Implementing Peer to Peer communication - java

I have 4 phones connected to a Wifi access point and I know the MAC/IP of all of these including the Wifi access point.
I need to implement communication between each of these phones, a sort of peer to peer communication, I was thinking about using sockets but then each phone will have to implement a ServerSocket and Socket on each of the phones is this fine?
The Ip's of these phones would be in private range 192.168.... so could I use something like http://192.168.xx.xx/port and contact any phone using http? What kind of classes could I use to implement this, or is there a ready framework that I could directly use?

What you are planning is just fine: you can have phones listen on sockets too. If you just want to have peer-to-peer communication and are more interested in the application you're writing, you might want to take a look at JXTA, which is a somewhat popular P2P system for Java. I don't know it, and I've heard some bad things about its performance, but for your application it could be suitable.
But it's not very hard to roll your own, either. However, I haven't seen any HTTP server-side libraries for Java ME, so using HTTP might be more work than necessary. I would probably just implement a custom protocol over TCP sockets, since it does not appear you would need to be interoperable with anything already in existence.
Socket communication in Java ME is through the Generic Connection Framework, found in the javax.microedition.io package, and from the client side it's exactly like using HTTP connections, i.e., something like
String url = "socket://192.168.xxx.xxx:12345";
SocketConnection conn = (SocketConnection) Connector.open(url);
And then you can get an InputStream and OutputStream for the connection from that, or DataInputStream and DataOutputStream if you want to send binary data.
On the server side you would do
String url = "socket://:12345";
ServerSocketConnection sock = (ServerSocketConnection) Connector.open(url);
SocketConnection conn = (SocketConnection) sock.acceptAndOpen();
The acceptAndOpen blocks until a connection is made, so if it is important for the server to be doing something else, make sure to put the connection acceptance into its own thread.
A caveat: when I was doing this a few years back, I found out that just listening on a socket does not turn on the network on all phones, so even though the server began listening, it was not possible to connect to it because it was not on the network. The way I worked around it was to open the Web browser on the phone, but any client opening a socket is enough, so you could also do it from the application by trying to open a client connection yourself.
There is also something called the Push Registry. When you create your Midlet, there is a possibility to register the application with a MIDlet-Push attribute in the JAD file, so that you don't have to have your application running but the system will wake it up when a connection is attempted on a certain port. I've never actually implemented this, so I cannot give any more advice on it.

Related

Connecting to an "online" server through java ServerSocket

Is it possible to connect to a server like "www.google.com" for example server side. Not actually connecting through google.com but that is the idea.
ServerSocket serverSocket = new ServerSocket(0, 50, InetAddress.getByName("www.google.com"));
This code returns null, I am new to this connection related stuff so I don't know exactly what that would be meaning.
This is the code I have currently for setting up the server, it works fine when using localhost, but I am unsure on how to continue with an actual domain and server so anyone can connect and communicate.
If it isn't possible to set up a server like that, what is the best way to implement and I am trying to do.
you can open raw sockets to whatever you want, but a ServerSocket is if you want to be a server, not if you want to connect to one; you'd use normal Socket for that.
sockets is for raw TCP/IP. You run some service on top of it. For example, HTTP or HTTPS, which is what the web runs on, is built on top of it.
I really doubt you want to write an HTTP client just for www.google.com, it's rather complicated. Fortunately, java has one built in. Don't use Socket, use HttpClient.
See the java HTTP client tutorial here.

Java sockets not connecting [duplicate]

I made a networked game in Java using Sockets. It works great, except... only through my LAN. :/ What I want to be able to do is set it up so that I can start the server running on my home computer and send the client code, in an executable jar, to someone else, and have them be able to launch it and connect through the internet. But like... I have no idea how to set up my modem & router for that. :( I have a wireless Clear modem, for which the configuration page looks like this:
http://imageshack.us/photo/my-images/254/modem.jpg
And a Netgear router, whose page looks like this:
http://imageshack.us/photo/my-images/443/routerq.jpg
Right now, in the client and server runner classes, I pass my PC's private IP address along with my chosen port number to the ServerSocket and Socket objects. I hear that Sockets are able to be either UDP or TCP, depending on how you set them up, or something...? I don't do anything like that though, I just instantiate them and pass them the 2 values, and off they go...
In the code for the server:
ServerSocket sock = new ServerSocket();
sock.bind(new InetSocketAddress(IP, 9001));
Code for the client:
Socket sock = new Socket(IP, 9001);
So also, I would need to know how to change the code accordingly with the changes to my router/modem settings.
"IP" is a String representing my computer's private IP, 192.168.1.10, and the program only works if that is the string I pass to the Socket & ServerSocket. Like I said, I have a modem which is connected to a router which is connected to my computer. So, can someone please explain to me (in detail, because I'm a noob) what exactly I would have to do to configure both of them, AND the changes I would have to make to my code?
You'll have to manually port forward, or look at a solution like UPnP or NAT-PMP for automatic port forwarding. Unfortunately, NAT is a pain in the ass to configure and most routers don't properly support it. It's also not a simple task, as you have to support a whole range of different implementations and mechanisms.
It shouldn't be too difficult to set up your router to forward one port to your machine, though. See http://portforward.com/ for an awesome list of how to do it on pretty much any router.
It sounds like you're asking a number of questions here... I'm no network/socket programming specialist, but here's some ideas.
For distribution, you may wish to look into Java Web Start. It'll make it easy for your clients to obtain the app as well as automating updates.
If you're using the Socket constructor like that, the actual implementation will be a system default. You could override this by calling this method with a suitable SocketImplFactory implementation.
As for the IP address and port... Using a hard-coded value for the port should be okay. You'll need to decide on a port or at least some default anyway for clients to connect to. Even so, it might be useful to have the value read from some external configuration file. This'll make it easier should you ever decide to distribute the server app to let other people run servers. They might want to use a different port.
Having the server's IP address (yours) hard-coded in code is definitely a no-no, though. Clients should connect using either an IP address or host name that they need to provide or set in some configuration file. A host name would be required if you don't have a static IP address.
Unless this is something for you and some friends to enjoy, where you can always just initiate a game by providing IP and port in a chat session or something, you'd be better off finding some external hosting solution at a company that takes care of the DNS resolution and network setup for you. These days you'll find stuff like that pretty cheap if you don't have requirements like a Java EE server or database.
EDIT: thought of something else. TCP might be okay for your use-case, but if this is a game that requires minimal lag and quick input synchronization (like a shooter or fighting game) then it's not the best choice. In that case UDP would be better. It would induce the requirement of adding some sort of detection for desync or a mechanism that makes up for any dropped packets.

java help understanding how socket connections work

I am completely new to creating a network connection in java so I apologize if this is a stupid question.
I am trying to create a D&D companion in java that will allow a player to create their character and then send it to the DM so that they can view it and make changes and send it back to the player. I want to be able to make it so that any time a field is changed on one computer it will also be changed on the other computer.
After a bunch of research online I have been able to create a socket connection between the DM(server) and the player(client) and pass a message between the two but I am not sure how a socket connection works after this initial connection is made. My research has not been very clear on this. I have found many resources that have said that java closes the socket after a message has been passed and many that say that the socket stays open.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message? (If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
If the server does not shout then how do I specify which client I want the server to talk to?
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client or will java automatically do so after I run the method the first time?
I have found many resources that have said that java closes the socket after a message has been passed
You found them where?
and many that say that the socket stays open.
All those are correct. Java never closes connections. The application closes connections.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
It doesn't.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message?
No. It will respond via the socket that is connected to the corresponding client.
(If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
Unnecessary.
If the server does not shout then how do I specify which client I want the server to talk to?
The server responds via the same socket it read the request from.
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client
No, you will have to add a thread per accepted socket, that loops reading requests until end of stream.
or will java automatically do so after I run the method the first time?
No.
You seem to have been reading some truly appalling drivel. Take a look at the Custom Networking section of the Java Tutorial.
Adding to EJP's wise answer, it might be worth clarifying:
Sounds like you (wisely) use TCP, so your Socket represents a connection between 1 server and 1 client. No "shouting". In examples such as this , when connection is established (namely, client obtains a Socket by calling "new Socket" and server obtains a Socket by calling "accept"), those Sockets are dedicated to those 2 specific endpoints. So if 10 clients connect to 1 server, the server will keep 10 Sockets and won't mix them up. A bit like a poor secretary that has 10 phones on his desk and answers them all - despite the mess, each earpiece is clearly connected to 1 customer.
The connection can hold for a while & serve several messages. It will terminate when either one of the sides calls 'socket.close', or it can be terminated by underlying 3rd parties (operating system, proxies, firewalls).
For your first version, or for simple business requirements, it's probably enough to converse over this 1 simple connection. However, for commercial critical data that requires 'assurance of delivery', you might need to invest some careful thought & possibly tools such as RabbitMQ.
Good luck:)

How do I access a ServerSocket behind an NAT router?

Goal
I'm making a chat application for android and am currently testing with 2 phones which must eventually work for a few thousand users.
Problem
I get a ConnectionException saying "Connection refused" whenever the 2 phones try connecting to each other via sockets.
Current Design
Each phone starts a ServerSocket, calls the accept() method waiting for some Socket to connect to, and whichever phone sends a message first will create a client Socket. I'm certain the IP addresses I'm using are correct (they're actually both using the same external IP).
I believe the problem is with the ports. I generate a port number at random, and if it's free to use, I say ServerSocket s = new ServerSocket( randomPortNumber ).
What I think is the source of the problem
What I think is the problem is this port number is one sitting behind an NAT router. So when a Socket tries to connect to the ServerSocket using something like Socket socket = new Socket( ip, serverSocketRandomPortNumber ), it will try to connect to the NAT router and feed it this port number which won't work since the router itself is not listening on this port, but the phone behind the router is.
Questions and thoughts
My question is, how do I deal with this problem?
Do I have to change my design?
If I must, an alternative design I'm thinking of is using a single ServerSocket on a web host and use it to redirect messages sent from client sockets to other client sockets.
I'd be implementing the server-side in php referencing something along these lines:
http://php.net/manual/en/sockets.examples.php
And I would still use Java for the client-side.
Since one of the phones is behind a NAT router, nothing can initiate a connection to it unless port forwarding (or some other techniques) is enabled on the router.
The usual way a chat application is implemented is, there is a common server that all clients will connect to.
You don't have to write your own chat server (unless you really want to). I suggest using the XMPP protocol. A list of already made servers here. On the client side (Android), you can find libraries you can use here.

Netty (Dummy) for existing service

There is an existing service that i would like to write a dummy service (using Netty) for. It will be used for testing purposes.
The existing client code fragment for the service looks like:
Socket socket = new java.net.Socket();
socket.connect(new InetSocketAddress("localhost", 8080), 10000);
socket.setSoTimeout(20000); // set a timeout of 20 seconds
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// write some string to the server and wait for answer
out.println("SomeCommand");
// server has written some answer, read it
char[] c = new char[2];
ir.read(c, 0, 2);
String cs = new String(c);
if ("OK".equals(cs.toString())) {
// write some more string's to the server
}
// we're done, close the connection
out.println("BYE");
out.close();
socket.close();
Is Netty the right framework to create a server for java.net.Socket connections? (If not, which framework should be used, if any?)
I am trying to find a way to start with Netty using the QuoteOfTheMoment example. The QuoteOfTheMomentServerHandler does basically what i want, upon the incoming message, return some answer so that the above snippet can read the answer using the inputstream but the above socket cannot make a connection to the QuoteOfTheMomentServer. The error is "connection refused".
[EDIT] More clarification:
The problem (i think) is not connecting or the port i use. Let me try to better ask the question:
I just started with netty (no nio experience) and am not familiar with the different types of channels, pipelines and what not.
The server should, like a servlet request/response (like, not http or trying to rebuild a http servlet impl), react on a inputString written to the output-stream as in the code fragment and write back some string/bytes to the input-stream as in the code fragment, so the client only then moves on. So the connection should stay open but also be synchronous, the client waits for answer from the server. If i use the example "Writing the Server Side of a Socket" in the java tutorial i am able to get it working for the client. But i want to utilize the thread handling etc. from netty.
The QuoteOfTheMomentServerHandler seems as server side implementation what i want but can that setup handle the given client code ?
So the question is which kind of pipeline, channel or something like that should be used given the way the client works ?
Again, the client and server are existing. I want to build a dummy server implementation to work with the existing client.
Netty is a TCP/IP framework. So yes if you are developing a TCP/IP server this toolkit is good to use.
I assume you are getting a error when trying to connect the client to the server. Also the server should also be running.
When getting a the connection refused error there are a couple of thine to check. First one is the firewall(if any) on the server allowing connections to port 8080? Secondly from your client machine try open a telnet session to the server something like:
Telnet yourserverip 8080
This opens a socket connection to the server. If you get a error message Google it.
The last one is that you might be running a server like tomcat, glassfish, IIS which uses port 8080 already. Try a non standard port like 10810 for example.
UPDATES:
If you are new to netty please read the users guide found here http://netty.io/docs/stable/guide/html/.
I had a look at the Quote of the moment service and I do believe I found part of the problem. The Quote of the moment service is a broadcast UDP/IP client and server. UDP is a much more lightweight "version" of TCP IP. It does not guarantee delivery to the client or server and it is broadcast. UDP is sort of like a radio broadcast as it is generally not targeted to a specific IP but broadcast over the entire network. Thus you normal TCP IP connection will not be able to work on the UDP server.
See this link on how to write a UDP Client http://systembash.com/content/a-simple-java-udp-server-and-udp-client/.
I would suggest that you convert the Quote of the moment server from UDP to TCP/IP server as this will give you some practise in creating a TCP/IP server without getting into too much detail. Once you are comfortable with that you should be able to start once from scratch.
Just remember that Netty handles the NIO part for you. It is a higher level framework based on NIO thus hiding a lot of the detail from you. You dont need to know NIO that well to use netty but you need to understand the Netty concepts well.

Categories