0

I am trying create a Server-Client chatting application using Java Socket on Android platform with Wifi P2P Connection for my college's thesis. The app will allow the Server to create a new Chat Room and the Client will join the Chat Room.

However, it always failed to send and receive messages when the first time Server and Client being on the Chat Room. It will success to send and receive messages when the Server and Client leave the Chat Room and create a new Chat Room.

There are my source code for send and receive message :

SendMessageServer.java

public class SendMessageServer extends AsyncTask<Message, Message, Message> {

private static final String TAG = "SendMessageServer";
private Context mContext;
private static final int serverPort = 4446;
private boolean isMine;

public SendMessageServer(Context context, boolean mine){
    mContext = context;
    isMine = mine;
}

@Override
protected Message doInBackground(Message... messages) {

    // Display Message Before Sending
    publishProgress(messages);

    // Send Message to Client
    try {
        ArrayList<InetAddress> listClients = ServerThread.clients;
        for(InetAddress addr : listClients) {
            if(messages[0].getSenderAddress()!=null && addr.getHostAddress().equals(messages[0].getSenderAddress().getHostAddress())) {
                return messages[0];
            }

            Socket socket = new Socket();
            socket.setReuseAddress(true);
            socket.bind(null);
            Log.v(TAG,"Connect to Client: " + addr.getHostAddress());

            socket.connect(new InetSocketAddress(addr, serverPort));
            Log.v(TAG,"Connect to " + addr.getHostAddress() + " Success");

            OutputStream outputStream = socket.getOutputStream();

            new ObjectOutputStream(outputStream).writeObject(messages[0]);
            Log.v(TAG, "Write to "+ addr.getHostAddress() + " Success");

            socket.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.v(TAG, "Send Message Server Error");
    }
    return messages[0];
}

@Override
protected void onProgressUpdate(Message... values) {
    super.onProgressUpdate(values);

    if(isActivityRunning(MainMenu.class)) {
        ChatActivity.refreshList(values[0], isMine);
    }
}

@Override
protected void onPostExecute(Message result) {
    super.onPostExecute(result);
}

@SuppressWarnings("rawtypes")
public Boolean isActivityRunning(Class activityClass) {
    ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

    for (ActivityManager.RunningTaskInfo task : tasks) {
        if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName())) {
            return true;
        }
    }
    return false;
}
}

SendMessageClient.java

public class SendMessageClient extends AsyncTask<Message, Message, Message> {

    private static final String TAG = "SendMessageClient";

    private Context mContext;
    private static final int serverPort = 4445;
    private InetAddress mServerAddress;

    public SendMessageClient(Context context, InetAddress serverAddress){
        mContext = context;
        mServerAddress = serverAddress;
    }

    @Override
    protected Message doInBackground(Message... messages) {
        // Display Message Before Sending
        publishProgress(messages);

        // Send the message
        Socket socket = new Socket();
        try {
            socket.setReuseAddress(true);
            socket.bind(null);
            socket.connect(new InetSocketAddress(mServerAddress, serverPort));
            Log.v(TAG, "Connect to Server : " + mServerAddress.getHostAddress() + " Success");

            OutputStream outputStream = socket.getOutputStream();
            new ObjectOutputStream(outputStream).writeObject(messages[0]);
            Log.v(TAG, "Send Message Client Success");
        } catch (IOException e) {
            e.printStackTrace();
            Log.v(TAG, "Send Message Client Error");
        } finally{
            if (socket != null) {
                if (socket.isConnected()) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.v(TAG, "Send Message Client Error");
                    }
                }
            }
        }
        return messages[0];
    }

    @Override
    protected void onProgressUpdate(Message... messages) {
        super.onProgressUpdate(messages);

        if(isActivityRunning(MainMenu.class)){
            ChatActivity.refreshList(messages[0], true);
        }
    }

    @Override
    protected void onPostExecute(Message result) {
        super.onPostExecute(result);
    }

    @SuppressWarnings("rawtypes")
    public Boolean isActivityRunning(Class activityClass) {
        ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

        for (ActivityManager.RunningTaskInfo task : tasks) {
            if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName())) {
                return true;
            }
        }

        return false;
    }
}

ReceiveMessageServer.java

public class ReceiveMessageServer extends AbstractReceiver {

    private static final String TAG = "ReceiveMessageServer";

    private static final int serverPort = 4445;
    private Context mContext;
    private ServerSocket serverSocket;

    public ReceiveMessageServer(Context context){
        mContext = context;
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            serverSocket = new ServerSocket(serverPort);
            while(true) {
                Socket clientSocket = serverSocket.accept();

                InputStream inputStream = clientSocket.getInputStream();
                ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
                Message message = (Message) objectInputStream.readObject();

                // Add Sender InetAddress to Message
                InetAddress senderAddress = clientSocket.getInetAddress();
                message.setSenderAddress(senderAddress);

                clientSocket.close();
                publishProgress(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.v(TAG, "Receive Message Failed : IOException");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.v(TAG, "Receive Message Failed : ClassNotFoundException");
        }
        return null;
    }

    @Override
    protected void onCancelled() {
        try {
            serverSocket.close();
            Log.v(TAG, "Server Socket Close Success");
        } catch (IOException e) {
            e.printStackTrace();
            Log.v(TAG, "Server Socket Close Failed");
        }
        super.onCancelled();
    }

    @Override
    protected void onProgressUpdate(Message... values) {
        super.onProgressUpdate(values);
        playNotification(mContext, values[0]);

        // Check Message Type exclude Text Message
        int type = values[0].getmType();
        if(type == Message.audioMessage || type == Message.fileMessage) {
            values[0].saveByteArrayToFile(mContext);
        }

        new SendMessageServer(mContext, false).executeOnExecutor(THREAD_POOL_EXECUTOR, values);
    }

}

ReceiveMessageClient.java

public class ReceiveMessageClient extends AbstractReceiver {

private static final String TAG = "ReceiveMessageClient";

private static final int serverPort = 4446;
private Context mContext;
private ServerSocket socket;

public ReceiveMessageClient(Context mContext) {
    this.mContext = mContext;
}

@Override
protected Void doInBackground(Void... params) {
    try {
        socket = new ServerSocket(serverPort);
        socket.setReuseAddress(true);
        while (true) {
            Socket destinationSocket = socket.accept();

            InputStream inputStream = destinationSocket.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            ObjectInputStream objectInputStream = new ObjectInputStream(bufferedInputStream);
            Message message = (Message) objectInputStream.readObject();

            destinationSocket.close();
            publishProgress(message);
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.v(TAG, "Receive Message Client Failed : IOException");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        Log.v(TAG, "Receive Message Client Failed : ClassNotFoundException");
    }
    return null;
}

@Override
protected void onCancelled() {
    try {
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    super.onCancelled();
}

@Override
protected void onProgressUpdate(Message... values) {
    super.onProgressUpdate(values);
    playNotification(mContext, values[0]);

    /* Check if the Message Contains Audio/Video/File
     * If true, Save to External Storage
    */
    int type = values[0].getmType();
    if (type == Message.audioMessage || type == Message.fileMessage){
        values[0].saveByteArrayToFile(mContext);
    }

    if (isActivityRunning(MainMenu.class)){
        ChatActivity.refreshList(values[0], false);
    }
}

public Boolean isActivityRunning(Class activityClass) {
    ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

    for (ActivityManager.RunningTaskInfo task : tasks) {
        if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
            return true;
    }

    return false;
}
}

The AbstractReceiver class is only for notification so i think the problem just come from those 4 class.

This is the Logcat when the error happened

07-18 21:06:31.952 12064-12426/com.archenians.inlesschat W/System.err: java.net.ConnectException: failed to connect to /192.168.49.220 (port 4446): connect failed: ECONNREFUSED (Connection refused)
07-18 21:06:31.955 12064-12426/com.archenians.inlesschat W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:129)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:188)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:457)
        at java.net.Socket.connect(Socket.java:927)
07-18 21:06:31.955 12064-12426/com.archenians.inlesschat W/System.err:     at java.net.Socket.connect(Socket.java:853)
07-18 21:06:31.955 12064-12426/com.archenians.inlesschat W/System.err:     at com.archenians.inlesschat.Asynctasks.SendMessageServer.doInBackground(SendMessageServer.java:53)
07-18 21:06:31.956 12064-12426/com.archenians.inlesschat W/System.err:     at com.archenians.inlesschat.Asynctasks.SendMessageServer.doInBackground(SendMessageServer.java:22)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
07-18 21:06:31.956 12064-12426/com.archenians.inlesschat W/System.err: Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
07-18 21:06:31.956 12064-12426/com.archenians.inlesschat W/System.err:     at libcore.io.Posix.connect(Native Method)
07-18 21:06:31.957 12064-12426/com.archenians.inlesschat W/System.err:     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111)
        at libcore.io.IoBridge.connectErrno(IoBridge.java:144)
        at libcore.io.IoBridge.connect(IoBridge.java:127)
        ... 11 more
07-18 21:06:31.957 12064-12426/com.archenians.inlesschat V/SendMessageServer: Send Message Server Error
07-18 21:06:31.974 12064-12177/com.archenians.inlesschat D/OpenGLRenderer: CacheTexture 3 upload: x, y, width height = 0, 28, 394, 382

It said the class SendMessageServer.java line 53

socket.connect(new InetSocketAddress(addr, serverPort));

It shows the same error on Client side.

EDIT :

Sending and Receive Message will be success if the Server and Client leave the Chat Room and create a new one. But, when it came success there is a new problem from the ServerThread.

There are my codes of ServerThread.java and ClientThread.java

ServerThread.java

public class ServerThread extends Thread {

    private static final String TAG = "ServerThread";

    private static final int SERVER_PORT = 4444;
    public static ArrayList<InetAddress> clients;
    private ServerSocket serverSocket;

    public ServerThread(){
        clients = new ArrayList<InetAddress>();
    }

    @Override
    public void run() {
        clients.clear();

        try {
            serverSocket = new ServerSocket(SERVER_PORT);
            // Collect IP Client
            while(true) {
                Socket clientSocket = serverSocket.accept();
                if(!clients.contains(clientSocket.getInetAddress())){
                    clients.add(clientSocket.getInetAddress());
                    Log.v(TAG, "New client: " + clientSocket.getInetAddress().getHostAddress());
                }

                clientSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void interrupt() {
        super.interrupt();
        try {
            serverSocket.close();
            Log.v(TAG, "Server init process interrupted");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

ClientThread.java

public class ClientThread extends Thread {

    public static final String TAG = "ClientThread";

    private static final int SERVER_PORT = 4444;
    private InetAddress mServerAddr;

    public ClientThread(InetAddress serverAddr){
        mServerAddr = serverAddr;
    }

    @Override
    public void run() {
        Socket socket = new Socket();
        try {
            socket.bind(null);
            socket.connect(new InetSocketAddress(mServerAddr, SERVER_PORT));
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

From the Server side, the error show on line :

serverSocket = new ServerSocket(SERVER_PORT);

This is the Bind Exception from Logcat

07-20 07:57:20.531 6417-6616/com.archenians.inlesschat W/System.err: java.net.BindException: bind failed: EADDRINUSE (Address already in use)
        at libcore.io.IoBridge.bind(IoBridge.java:104)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:137)
07-20 07:57:20.532 6417-6616/com.archenians.inlesschat W/System.err:     at java.net.ServerSocket.<init>(ServerSocket.java:106)
        at java.net.ServerSocket.<init>(ServerSocket.java:75)
        at com.archenians.inlesschat.Threads.ServerThread.run(ServerThread.java:28)
    Caused by: android.system.ErrnoException: bind failed: EADDRINUSE (Address already in use)
        at libcore.io.Posix.bind(Native Method)
07-20 07:57:20.533 6417-6616/com.archenians.inlesschat W/System.err:     at libcore.io.ForwardingOs.bind(ForwardingOs.java:56)
        at libcore.io.IoBridge.bind(IoBridge.java:102)
        ... 4 more 

I have been try add a

setReuseAddress(true);

But the Sending Message will never success again even if the Server and Client close the Chat Room and create a new one again.

Can anybody helps me?

Show me where is my fault on these codes and how to fix it.

Archenians
  • 11
  • 2
  • Nothing was listening on port 4446, or the target IP address was wrong. – user207421 Jul 18 '18 at 16:26
  • @EJP : how to fix my problem? please tell me how to fix it – Archenians Jul 19 '18 at 04:08
  • First describe it accurately, in your title and your question. It was never a case of 'trouble sending message'. First it was a connection refusal, and now it has magically become a bind exception. Please make up your mind. – user207421 Jul 20 '18 at 00:18
  • @EJP : First, i am sorry that i couldn't set a perfect title because i still don't know what is really problem on my case. Thats why i become confused. There is problem on Connection on the first try and if i close the room and create a new one, it will success on the connection but show a bind exception. could you help me how to fix it, please? – Archenians Jul 20 '18 at 00:21
  • Somebody may help you *if you fix your question.* Including the title. And post the `BindException` stack trace. – user207421 Jul 20 '18 at 00:24
  • @EJP: I had updated my title. Is that better? or you can suggest me a perfect title. This time, can you explain about your first comment about Nothing was listenting or the target IP address was wrong? – Archenians Jul 20 '18 at 00:38
  • The second problem came when the server and client close the chat room and create a new one. I don't the app become like this. How to fix the first problem? so the connection will be success in the first try. Please show me – Archenians Jul 20 '18 at 00:40
  • No, it isn't better. It still mentions a non-existent problem sending messages; it doesn't mention either the connect exception or the bind exception; and you still haven't posted the bind exception stack trace. And NB nobody is attempting to answer via comment here. All you're getting is requests for clarifications which you aren't actioning very well. – user207421 Jul 20 '18 at 00:43
  • @EJP: Is that better now? I had updated the title and posted the bind exception. I asked you to explain because i don't understand with your first comment. Can you give me an explanation or a reference for me to solve the problem? – Archenians Jul 20 '18 at 01:08

0 Answers0