Hot questions for Using Transmission Control Protocol in serversocket

Question:

I have made a game named Two Dice Pig in java. The game has a simple GUI interface showing two dice faces as well as both players scores and names. The game starts with the simple dialog message asking for both players' name and the game starts. Both players interact with only one GUI interface and play as their turn come. The game is completely coded. Now, what I want is to make a server (For now I want to try it on my local server) and both players should get their own GUI. And when a player A is playing, player B should not be able to do anything with the interface. I hope it clears. It's my networking project, but I don't have any idea how to do that. Any help would be greatly appreciated.

Note: I want to apply the same idea as this man applied. Just watch only for 15 seconds. Thanks!,


Answer:

You should start googling "Rest Services with Java" or something like this.

You need some central component, that manages the game state of your two android game sessions. For example you have a url like localhost://myService/Dice where you would POST a new dice throw. If somebody else makes a GET to that ressource, he would be able to retrieve the thrown dice you have posted during the game. If you do not want the player to be able to interact, you could forbid a player to POST a new Dice when he is not able to do that and the GUI should reflect that somehow. Maybe disable buttons after you posted a Dice or something like that.

There is much more to it, but this should get you started somehow.

https://docs.oracle.com/javaee/6/tutorial/doc/gilik.html

the important code part from the url above would be the hello world like this:

package com.sun.jersey.samples.helloworld.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

// The Java class will be hosted at the URI path "/helloworld"
@Path("/helloworld")
public class HelloWorldResource {

    // The Java method will process HTTP GET requests
    @GET
    // The Java method will produce content identified by the MIME Media
    // type "text/plain"
    @Produces("text/plain")
    public String getClichedMessage() {
        // Return some cliched textual content
        return "Hello World";
    }
}

Question:

I have two android devices and they are connected to a same WiFi network. One device acts as the server and the other acts as the client. I don't know the ip of the server but I know the port number. How can I find the server and connect to it?


Answer:

One option is to use UDP broadcasting. Your server is waiting for requests on a specific port and network interface. Then your client send a dummy request against the broadcast address (like for instance 192.168.1.255) and once the server replies you can get the server's ip address.

Once you're done, the client can shutdown the udp socket connection and start tcp communication as you need.

A good start might be this: http://michieldemey.be/blog/network-discovery-using-udp-broadcast/

Hope this helps

Question:

I am working on an app,I have made a TCP Listner which is working fine on wifi network but when i am connected to 3G/4G or mobile network it does not work.Can some body help me here? my code is here

public class ListenerService  extends Service {

Socket socket;
private ServerSocket serverSocket;
BufferedReader in = null;
static String message=null;
int portNo=1619;
boolean flag=true;
final static String MY_ACTION = "MY_ACTION";
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    new Task().execute();

}

    private class Task extends AsyncTask <Void, String, String> {
        @Override
        protected String doInBackground(Void... params) {    
        try {
            serverSocket = new ServerSocket(portNo);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        while (flag) {
            try {

                socket = serverSocket.accept();
                in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));
                //try {
                    StringBuilder total = new StringBuilder();
                    String line;
                    while ((line = in.readLine()) != null) {
                        total.append(line);
                    }
                    message = total.toString();
                    Log.d("NETWORK-RECEIVE", "Message!:" + message);



            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        try {

            serverSocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return message;
        }
   }

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    Log.d("Server Startd","Listener Serverice is running");
    //Toast.makeText(getApplicationContext(),"Service Started", Toast.LENGTH_LONG).show();
    return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

}

can some tell me what m i missing here?


Answer:

You are trying to connect two devices over TCP connected to two different subnets. That's impossible. You are pretty much asking the question: "Why can my friend hear me when he's standing in front of me, but not if he's in another room?" The only way to make that work is to open the door. But you'd have to implement this "door", which is called NAT traversal or "hole punching" and really is a different communication concept (check Android P2P (direct-connection) over the Internet (behind NAT) and Android: NAT Traversal?).

In the end, there are three solutions to your problem:

  1. Implement your own server to put between those devices you want to connect (very tedious).
  2. Use a 3rd-party library like sip2peer or whatever else you can find that suits you.
  3. Don't bother. Sometimes it's just not worth the trouble.

Edit: It sounds like you have a web server that is trying to connect to an Android device running the code above. That would be option 1, but still, an Android device can't be reached over the Internet. As far as I know, you have to turn that around: The device has to register itself on the server so that the server can kind of "connect" other devices to it.

Question:

In a TCP connection between sockets. What is the correct procedure to closing/shutting down the connection?

I have outputstreams, bufferedreaders and printwriters. Will closing the socket close all of them? Should they be closeds at both ends?(server and client)


Answer:

  • You should close the outermost stream or writer you have wrapped around the socket output stream. That way it will get flushed if it is buffered.
  • Closing either the input or output stream or the socket closes everything else.
  • 'Should they be closed at both ends?' doesn't really make sense. Sockets don't have two ends: connections do. The connection must be closed at both ends, but both ends have a socket, and all sockets must be closed.

Question:

I'm currently developing an online game. Within the game it is necessary to send data from the server to the clients via TCP and UDP. Implementing UDP-Hole Punching is easy, but I'm not really sure how to implement TCP-hole punching:

  1. Server: ServerSocket listening on given port 1
  2. Client: Socket (object) connects to server on port 1 using port 2
  3. Once the connection is established, the server keeps the Socket object from server.accept() and uses it to send data to client for the remaining time
  4. Once the connection is established, the client closes its Socket object and opens a ServerSocket on port 2. The server is now able to send data using a Socket object on port 1 to port 2.

Is 3. or 4. the right way to go?


Answer:

Option 3.

Option 4 does not work because once the client closes the socket BOTH sides shut down. The server would have to initiate the connection across the NAT firewall, which clearly doesn't work.

Question:

So I am running a piece of code that is supposed to create a Socket a ServerSocket, when I run my code it meets a stand still at line 14 but doesn't throw any exception. What have I missed?

public class Syncronizer {

    InputStream instr = null;
    PrintStream prnstr = null;
    BufferedReader br = null;
    DataInputStream in;
    DataOutputStream out;
    ServerSocket TCPServerSocket;

    public Syncronizer() {
        try {
            instr = System.in;
            br = new BufferedReader(new InputStreamReader(instr));
            TCPServerSocket = new ServerSocket(7007);
            Socket clientSocket = TCPServerSocket.accept();
            in = new DataInputStream(clientSocket.getInputStream());
            out = new DataOutputStream(clientSocket.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    ...
}

Just to spare you the counting it is this line that halts my program:

Socket clientSocket = TCPServerSocket.accept();

EDIT: With halt I mean that my program still runs but doesn't go beyond this point in the code just like a infinite loop.


Answer:

accept() is expected to block until a connection comes in on the port the socket the code calls accept() for is listening on.

You might like to RTFM here: http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept%28%29

Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.