2

我写了一个 WiFi-Direct 代码连接并在它们之间创建了一个连接,然后我在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);
    }
}
4

1 回答 1

2

以防万一有人遇到类似问题,我有时会遇到类似的问题,即有时会看到连接被拒绝消息,并通过允许客户端线程休眠一秒钟以防止出现竞争情况来解决此问题。这个想法是,一旦连接了两个设备,ConnectionListener 就会被触发。之后,server\client 都会根据角色启动 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();

    }
}

};
于 2014-03-24T18:21:39.283 回答