Android连接有时被拒绝(并非所有时间)

时间:2013-09-09 10:38:07

标签: android sockets

我写了一个WiFi-Direct Code连接并在它们之间创建了一个连接,然后我在第一面创建了一个ServerSocket,在客户端创建了一个Socket并开始在它们之间发送数据,我第一次启动应用程序它成功运行,但当我关闭应用程序并再次启动它时,它给了我一个例外,说“连接拒绝ECONNREFUSED” 这是我在服务器端的代码:

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);
    }
}

此代码位于服务器端,以下代码位于客户端:

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);
    }

}

这是班级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);
    }
}

最后这是我的主要活动类

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);
    }
}

1 个答案:

答案 0 :(得分:2)

为了防止有人遇到类似的问题,我遇到了类似的问题,有时会看到连接拒绝消息并通过允许客户端线程修复此问题,以暂停一秒以防止竞争条件。这个想法是,一旦连接了两个设备,ConnectionListener就会被触发。之后,server \ client将根据角色启动服务器线程或客户端线程。组所有者将发出服务器线程,组成员将启动客户端线程。有时,客户端线程将在服务器线程之前启动,而那些客户端线程无法找到要连接的服务器。因此,我为客户端添加了一秒睡眠,以确保首先注册服务器线程。现在,我没有看到问题发生。这是我的代码:

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();

    }
}

};