YahyaKhalid
YahyaKhalid

Reputation: 23

Android connection refuses sometimes (Not all times)

I wrote a WiFi-Direct Code connection and created a connection between them, then I created a ServerSocket on the first side and a Socket on the client side and started sending data between them, the first time I start the application it works Successfully, but when I close the Application and start it again it gives me an exception that says "Connection Refused ECONNREFUSED" here is my code in the Server side:

package com.example.serverwifidirect;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class BroadcastServer extends BroadcastReceiver
{
    @SuppressLint("NewApi")
    private WifiP2pManager mManager;
    private Channel mChannel;
    private Server mActivity;
    static boolean temp=false;
    Socket client=null;
    static boolean isRunning = false;
    ServerSocket serverSocket = null;
    InetSocketAddress inet;
    private void closeConnections()
    {
        try
        {
            if(client!=null || serverSocket!=null)
            {
                if(client!=null)
                {
                    if(client.isInputShutdown()|| client.isOutputShutdown())
                    {
                        log("x1");
                        client.close();
                    }
                    if(client.isConnected())
                    {
                        log("x2");
                        client.close();
                        log("x2.1");
                        //client.bind(null);
                        log("x2.2");
                    }
                    if(client.isBound())
                    {
                        log("x3");
                        client.close();
                    }
                    client=null;
                }
            }
        }
        catch(Exception e)
        {
            log("Error :'(");
            e.printStackTrace();
        }
    }
    @SuppressLint("NewApi")
    public BroadcastServer(WifiP2pManager manager, Channel channel, Server activity) 
    {
        super();
        this.mManager = manager;
        this.mChannel = channel;
        this.mActivity = activity;
        try
        {
            serverSocket = new ServerSocket(8870);
            serverSocket.setReuseAddress(true);
        }
        catch(Exception e)
        {
        }
    }
    @SuppressLint("NewApi")
    @Override
    public void onReceive(Context context, Intent intent)
    {
        String action = intent.getAction();
        if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action))
        {
            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
            if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED)
            {}
            else
            {}
        }
        else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action))
        {
            mManager.requestPeers(mChannel, new PeerListListener()
            {
                @Override
                public void onPeersAvailable(WifiP2pDeviceList list)
                {
                }
            });
        } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action))
        {
            Bundle b = intent.getExtras();
            NetworkInfo info = (NetworkInfo)b.get(WifiP2pManager.EXTRA_NETWORK_INFO);
            if(info.isFailover())
            {
                temp=false;
            }
            else if(info.isConnected())
            {
                temp=true;
                log("c1");
                new Thread(new Runnable(){
                    public void run()
                    {
                        try
                        {
                            client =serverSocket.accept();
                            InputStream input=null;
                            input = client.getInputStream();
                            log("q3");
                            while(BroadcastServer.temp)
                            {
                                final int n = input.read();
                                if(n==100)
                                {
                                    closeConnections();
                                    mManager.cancelConnect(mChannel, new ActionListener() {

                                        @Override
                                        public void onSuccess() 
                                        {
                                            log("done");
                                            mManager.removeGroup(mChannel, new ActionListener() 
                                            {
                                                @Override
                                                public void onSuccess() 
                                                {
                                                    log("group removed");
                                                }

                                                @Override
                                                public void onFailure(int reason) 
                                                {
                                                    log("fail!!!!!");
                                                }
                                            });
                                        }
                                        @Override
                                        public void onFailure(int reason) {
                                        log("fail");
                                            mManager.removeGroup(mChannel, new ActionListener() 
                                            {
                                                @Override
                                                public void onSuccess() 
                                                {
                                                    log("group removed");
                                                }

                                                @Override
                                                public void onFailure(int reason) 
                                                {
                                                    log("fail!!!!!");
                                                }
                                            });
                                        }
                                    });
                                }
                                log("q4");
                                if(n==-1)
                                {
                                    log("n = -1");
                                    break;
                                }
                                log("n= "+n);
                                mActivity.runOnUiThread(new Runnable()
                                {
                                    public void run()
                                    {
                                        Toast.makeText(mActivity.getBaseContext(), "--"+n, Toast.LENGTH_SHORT).show();  
                                    }
                                });

                            }
                            log("After loop");
                        }
                        catch(Exception e)
                        {
                        }
                    }
                });
                mActivity.runOnUiThread(new Runnable(){
                        public void run()
                        {
                            //Toast.makeText(mActivity, "Connected to WiFi-Direct!", Toast.LENGTH_SHORT).show();                                
                        }
                    });

                log("c2");
            }
            else if(info.isConnectedOrConnecting())
            {
                temp=false;
            }
            else if(!info.isConnected())
            {

                temp=false;
                try
                {

                    if(client!=null || serverSocket!=null)
                    {
                        if(client!=null)
                        {
                            if(client.isInputShutdown()|| client.isOutputShutdown())
                            {
                                log("x1");
                                client.close();
                            }
                            if(client.isConnected())
                            {
                                log("x2");
                                client.close();
                                log("x2.1");
                                //client.bind(null);
                                log("x2.2");
                            }
                            if(client.isBound())
                            {
                                log("x3");
                                client.close();
                            }
                            client=null;
                        }
                    }
                }
                catch(Exception e)
                {
                    log("Error :'(");
                    e.printStackTrace();
                }
                mManager.clearLocalServices(mChannel, new ActionListener() 
                {
                    @Override
                    public void onSuccess() 
                    {
                        log("success");
                    }
                    @Override
                    public void onFailure(int reason) 
                    {   
                    }
                });
            }
        }
        else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action))
        {
            log("Device change Action!");
        }
    }
    public static void log(String shusmu)
    {
        Log.d("status", shusmu);
    }
}

this code is in the Server side, and the following code is in the Client side:

package com.example.wifidirect;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;

@SuppressLint("NewApi")
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver 
{
    static WifiP2pDevice connectedDevice = null;
    boolean found=false;
    boolean connected = false;
    private WifiP2pManager mManager;
    private Channel mChannel;
    Button find = null;
    Activity mActivity = null;
    @SuppressLint("NewApi")
    public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, WifiDirect activity) 
    {
        super();

        this.mManager = manager;
        this.mChannel = channel;
        mActivity = activity;
        find = (Button)mActivity.findViewById(R.id.discover);
    }
    @SuppressLint("NewApi")
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        String action = intent.getAction();
        if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) 
        {
            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
            if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) 
            {
                // Wifi Direct is enabled
            } else 
            {
                // Wi-Fi Direct is not enabled
            }
        }
        else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) 
        {
            mManager.requestPeers(mChannel, new PeerListListener() 
            {
                @Override
                public void onPeersAvailable(WifiP2pDeviceList list) 
                {
                    WifiP2pDevice d = null;
                    if(!found)
                    {
                        Log.d("status", "2");
                        Collection<WifiP2pDevice>li = list.getDeviceList();
                        ArrayList<WifiP2pDevice> arrayList = new ArrayList<WifiP2pDevice>();
                        Iterator<WifiP2pDevice>peers = li.iterator();
                        while(peers.hasNext())
                        {
                            WifiP2pDevice device = peers.next();
                            arrayList.add(device);
                        }

                        for(int i=0;i<arrayList.size();i++)
                        {
                            log("xxx");
                            log(arrayList.get(i).deviceName);
                            if(arrayList.get(i).deviceName.equalsIgnoreCase("Android_144b"))
                            { 
                                d = arrayList.get(i);
                                arrayList.clear();
                                found = true;
                                break;
                            }
                        }
                    }
                    if(d!=null)
                    {

                            WifiP2pConfig config = new WifiP2pConfig();
                            config.deviceAddress = d.deviceAddress;
                            if(!connected)
                            {
                                mManager.connect(mChannel, config, new ActionListener() 
                                {
                                    @Override
                                    public void onSuccess() 
                                    {
                                        connected = true;
                                    }
                                    @Override
                                    public void onFailure(int reason) 
                                    {
                                        connected=false;
                                        mManager.cancelConnect(mChannel, new ActionListener() 
                                        {
                                            @Override
                                            public void onSuccess() 
                                            {
                                                Log.d("status", "success on cancelConnect()");
                                            }
                                            @Override
                                            public void onFailure(int reason) 
                                            {   
                                                Log.d("status", "Fail on cancelConnect()");
                                            }
                                        });
                                    }
                                });
                            }
                        }
                    }
            });
        } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) 
        {
            Bundle b = intent.getExtras();
            NetworkInfo info = (NetworkInfo)b.get(WifiP2pManager.EXTRA_NETWORK_INFO);
            if(info.isFailover())
            {
                connected=false;
                Log.d("status", "connection failure!");
            }
            else if(info.isConnected())
            {
                connected=true;
                find.setEnabled(false);
                Log.d("status", "connection is Connected!");
            }
            else if(info.isConnectedOrConnecting())
            {
                connected=false;
                log("Connecting !!!");
            }
            else if(!info.isConnected())
            {
                if(connected)
                {
                    //closeConnections();
                    connected=false;
                }
                find.setEnabled(true);
                mManager.removeGroup(mChannel, new ActionListener() 
                {
                    @Override
                    public void onSuccess() 
                    {   
                        log("Success disconnect");
                    }
                    @Override
                    public void onFailure(int arg0) 
                    {   
                        log("Fail disconnect");
                    }
                });
            }
        }
        else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) 
        {}
    }
    public static void log(String shusmu)
    {
        Log.d("status", shusmu);
    }

}

And this is the class Connection

package com.example.wifidirect;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.annotation.SuppressLint;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

@SuppressLint("NewApi")
public class Connection 
{
    boolean found = false;
    OutputStream out=null;
    Socket socket = null;
    boolean connected =false;
    WiFiDirectBroadcastReceiver mReceiver=null;
    WifiDirect instance=null;
    @SuppressLint("NewApi")
    Channel mChannel=null;
    WifiP2pManager mManager=null;
    public void sendMessage(int msg)
    {
        try
        {
            out.write(msg);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    public Connection(WiFiDirectBroadcastReceiver mReceiver,WifiDirect instance,Channel mChannel,WifiP2pManager mManager) throws UnknownHostException, IOException
    {
        this.instance=instance;
        this.mReceiver=mReceiver;
        this.mChannel=mChannel;
        this.mManager= mManager;
        socket = null;
        Button send = (Button)instance.findViewById(R.id.send);
        send.setOnClickListener(new OnClickListener() 
        {   
            @Override
            public void onClick(View arg0) 
            {
                try
                {
                    log("z1");
                    if(socket==null)
                    {
                        log("z2");
                        Thread t = new Thread(new Runnable()
                        {
                            public void run()
                            {
                                try
                                {
                                    log("z3");
                                    socket= new Socket("192.168.49.1",8870);
                                    socket.setReuseAddress(true);
                                    log("z4");
                                    out = socket.getOutputStream();
                                    connected = true;
                                }
                                catch(Exception e)
                                {
                                    e.printStackTrace();
                                }
                            }   
                        });
                        t.setDaemon(false);
                        t.start();
                    }

                    new Thread(new Runnable()
                    {
                        public void run()
                        {
                            log("trying to Send !");
                            while(!connected);
                            sendMessage(10);
                            log(" Data sent !");
                        }
                    }).start();


                }
                catch(Exception e)
                {
                    log("exception_1");
                    e.printStackTrace();
                    log("exception_2");
                    log(e.getMessage());
                }
            }
        });
    }
    public void closeConnections()
    {
        try
        {
            if(out!=null)
            {
                out.close();
                out=null;
            }
            if(socket!=null)
            {
                socket.shutdownInput();
                socket.shutdownOutput();
                if(socket.isInputShutdown()|| socket.isOutputShutdown())
                {   
                    socket.close();
                }
                if(!socket.isClosed())socket.close();
            }
            if(socket.isConnected())
            {
                socket.close(); 
            }
            socket=null;
        }
        catch(Exception e)
        {
            Log.d("status", "error :( ");
            e.printStackTrace();
        }
    }
    public void connect()
    {
        mManager.discoverPeers(mChannel, new ActionListener() 
        {
            @Override
            public void onSuccess()
            {
                Log.d("status", "1");
            }
            @Override
            public void onFailure(int reason) 
            {
                mManager.cancelConnect(mChannel, new ActionListener() {
                    @Override
                    public void onSuccess()
                    {
                        Log.d("status", "success cancel connect");
                        connect();
                    }
                    @Override
                    public void onFailure(int reason) 
                    {
                        Log.d("status", "failed cancel connect");
                    }
                });
            }
        });
    }
    public static void log(String shusmu)
    {
        Log.d("status", shusmu);
    }
}

finally this is my main Activity class

package com.example.wifidirect;
import java.io.IOException;
import java.net.UnknownHostException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class WifiDirect extends Activity 
{
    WifiP2pManager mManager;
    Channel mChannel;
    WiFiDirectBroadcastReceiver mReceiver;
    PeerListListener listener = null;
    IntentFilter mIntentFilter;
    String host;
    Connection con=null;
    PeerListListener myPeerListListener;
    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.wifi_direct);
        StrictMode.enableDefaults();
        WifiManager wifiManager  = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
        wifiManager.setWifiEnabled(true);
        mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        mChannel = mManager.initialize(this, getMainLooper(), null);
        mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
        try {
            con = new Connection(mReceiver,this,mChannel,mManager);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        final Button discover = (Button)findViewById(R.id.discover);
        discover.setOnClickListener(new OnClickListener() 
        {
            @Override
            public void onClick(View v) 
            {
                con.connect();
            }
        });
    }
    @Override
    protected void onResume()
    {
        super.onResume();
        registerReceiver(mReceiver, mIntentFilter);
    }
    @Override
    protected void onPause() {
        super.onPause();
    }
    @SuppressLint("NewApi")
    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        con.sendMessage(100);
        unregisterReceiver(mReceiver);
    }
    @SuppressLint("NewApi")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        String action = data.getAction();
        if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) 
        {
            if (mManager != null) 
            {
                mManager.requestPeers(mChannel, myPeerListListener);
            }
        }
    }
    void log(String s)
    {
        Log.d("status ", s);
    }
}

Upvotes: 2

Views: 2649

Answers (1)

Khaled Alanezi
Khaled Alanezi

Reputation: 361

Just in case someone run into similar issue, I was having similar problem of seeing connection refused messages sometimes and fixed this by allowing client thread,to sleep for a second to prevent race conditions. The idea is that once two devices are connected, the ConnectionListener gets fired. After that, both server\client will launch server thread or client thread based on the role. A group owner will issue a server thread and group member will launch a client thread. Sometimes, the client thread will launch before the server thread and those fail to find a server to connect to. So, I added a one-second-sleep for the client to ensure that server thread gets registered first. Now, I don't see the problem happening. Here is my code:

private WifiP2pManager.ConnectionInfoListener connectionListener
  = new WifiP2pManager.ConnectionInfoListener(){
    @Override
    public void onConnectionInfoAvailable(WifiP2pInfo info) {

            // TODO Auto-generated method stub                  
    Log.i(TAG, "onConnectionInfoAvailable");

    //String groupOwnerAddress = info.groupOwnerAddress.getHostAddress();
    if (info.groupFormed && info.isGroupOwner) {
        // Do whatever tasks are specific to the group owner.
        // One common case is creating a server thread and accepting
        // incoming connections.
        Log.i(TAG, "Connected as group owner...");
        WifiDirectServerThread wifiDirectServerThread = new WifiDirectServerThread(context);
        wifiDirectServerThread.execute();

    } else if (info.groupFormed) {
        // The other device acts as the client. In this case,
        // you'll want to create a client thread that connects to the group
        // owner.
        Log.i(TAG, "Connected as group member...");
        Log.i(TAG, "Sleep before launching client thread to avoid race conditions...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        WifiDirectClientDataThread wifiDirectClientThread = new WifiDirectClientDataThread(info.groupOwnerAddress.getHostAddress(), PORT, context);
        wifiDirectClientThread.start();

    }
}

};

Upvotes: 2

Related Questions