使用Wi-Fi创建P2P连接:消息传递问题

时间:2017-04-14 07:07:16

标签: android android-wifi p2p wifi-direct wifip2p

我正在使用Wifi P2P Connection在两个Android设备之间使用以下教程发送和接收消息

https://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html

https://developer.android.com/guide/topics/connectivity/wifip2p.html

它正在努力识别附近的设备并与附近的对等设备连接。但是在我的代码中,在服务器和客户端之间连接成功后,客户端对等体正在向服务器对等体发送消息,因为服务器对等体无法向客户端对等体发送消息。它给出了以下异常

04-14 12:31:27.740: E/test(6037): SERVER to CLIENT message sending exception: bind failed: EADDRINUSE (Address already in use)

请帮助查找我的代码有什么问题

这是我的MainActivity.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
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.ConnectionInfoListener;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener, PeerListListener, ConnectionInfoListener{

WifiP2pManager mManager;
Channel mChannel;
private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
private BroadcastReceiver receiver = null;
private WifiP2pInfo info;
String groupOwnerAddress;

ListView listPeers;
TextView mTextDeviceName, mTextStatus, mTextGroupOwner;
EditText mEditText_message;
Context context;
static String toastmessage;
static String message = "";
boolean isPeerServer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    context = MainActivity.this;
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    mChannel = mManager.initialize(this, getMainLooper(), null);
    mReceiver = new WifiP2PBroadCast(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);

    findViewById(R.id.button_search).setOnClickListener(this);
    findViewById(R.id.button_send).setOnClickListener(this);

    listPeers = (ListView) findViewById(R.id.list_peers);
    mTextDeviceName = (TextView) findViewById(R.id.text_device_name);
    mTextStatus = (TextView) findViewById(R.id.text_Status);
    mTextGroupOwner = (TextView) findViewById(R.id.text_group_owner);
    mEditText_message = (EditText) findViewById(R.id.edittext_message);

    listPeers.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
            // TODO Auto-generated method stub
            connectWithPeers(position);
        }
    });
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    receiver = new WifiP2PBroadCast(mManager, mChannel, this);
    registerReceiver(mReceiver, mIntentFilter);
    discoverPeers();
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(mReceiver);
}

public void updateDeviceInfo(WifiP2pDevice device) {
    mTextDeviceName.setText(device.deviceName);
    mTextStatus.setText(getDeviceStatus(device.status));
}

private static String getDeviceStatus(int deviceStatus) {
    switch (deviceStatus) {
        case WifiP2pDevice.AVAILABLE:
            return "Available";
        case WifiP2pDevice.INVITED:
            return "Invited";
        case WifiP2pDevice.CONNECTED:
            return "Connected";
        case WifiP2pDevice.FAILED:
            return "Failed";
        case WifiP2pDevice.UNAVAILABLE:
            return "Unavailable";
        default:
            return "Unknown";
    }
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
        case R.id.button_search:
            discoverPeers();
            break;
        case R.id.button_send:
            sendMessage();
            break;
        default:
            break;
    }

}

public void discoverPeers(){
    mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            Log.e("test", "Discovering Peers Success..");
            if (mManager != null) {
                mManager.requestPeers(mChannel, MainActivity.this);
            }
        }

        @Override
        public void onFailure(int reasonCode) {
           Log.e("test", "Discovering Peers Fail..");
        }
    });
}

public void connectWithPeers(int id) {
    WifiP2pDevice device = peers.get(id);
    WifiP2pConfig config = new WifiP2pConfig();
    config.deviceAddress = device.deviceAddress;
    mManager.connect(mChannel, config, new ActionListener() {

        @Override
        public void onSuccess() {
            //success logic
            Log.e("test", "Connection with peer Success..");
        }

        @Override
        public void onFailure(int reason) {
            //failure logic
            Log.e("test", "Connection with peer Failed..");
        }
    });
}

public void sendMessage() {
    if (!isPeerServer) {
        //Client Peer
        Toast.makeText(MainActivity.this, "client sending message", Toast.LENGTH_SHORT).show();
        new SendMessage().execute(MainActivity.this);
    } else {
        //Server Peer
        Toast.makeText(MainActivity.this, "server sending message", Toast.LENGTH_SHORT).show();
        new FileServerAsyncTask(this, "").execute();
    }

}

//Send message form client to server
public class SendMessage extends AsyncTask {
    @Override
    protected Object doInBackground(Object... arg0) {
        // TODO Auto-generated method stub
        try {
            message = mEditText_message.getText().toString();

            Socket socket = new Socket(info.groupOwnerAddress.getHostAddress(), 8988);
            //Send the message to the server
            OutputStream os = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(os);
            BufferedWriter bw = new BufferedWriter(osw);

            String number = message;

            String sendMessage = number + "\n";
            bw.write(sendMessage);
            bw.flush();
            Log.e("test", "Message sent to the server : "+sendMessage);

            //Get the return message from the server
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String message = br.readLine();
            Log.e("test", "Message received from the server : " +message);
            socket.close();
        }catch(IOException e){
            Log.e("test", "CLIENT to SERVER message sending exception: "+e.getMessage());
        }finally {
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        Toast.makeText(MainActivity.this, "MESSAGE: "+message, Toast.LENGTH_SHORT).show();
    }

}

@Override
public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
    // TODO Auto-generated method stub
    Log.e("test", "..onConnectionInfoAvailable..");
    info = wifiP2pInfo;
    try {
        groupOwnerAddress = wifiP2pInfo.groupOwnerAddress.getHostAddress();
    } catch (Exception e) {
        // TODO: handle exception
        Log.e("test", "Owner Info null");
    }

    if (info.groupFormed && info.isGroupOwner) {
        Log.e("test", "GOT INFORMATION FROM PEERS..");
        new FileServerAsyncTask(this, "").execute();
    }
    if (wifiP2pInfo.isGroupOwner) {
        isPeerServer = true;
    } else {
        isPeerServer = false;
    }
    mTextGroupOwner.setText("Is group owner? ---- "+((wifiP2pInfo.isGroupOwner == true) ? "yes" : "no"));
}

@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
    // TODO Auto-generated method stub
    Log.e("test", "NUMBER OF PEERS AVAILABLE: ----- "+peerList.getDeviceList().size());
    peers.clear();
    peers.addAll(peerList.getDeviceList());

    String[] devices = new String[peerList.getDeviceList().size()];
     for (int i = 0; i < devices.length; i++) {
        devices[i] = peers.get(i).deviceName.toString();
     }

     try {
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.simplerow, devices);
         listPeers.setAdapter(adapter); 
     }catch (Exception e) {
        // TODO: handle exception
        Log.e("test", "EXCEPTION: "+e.toString());
     }

}

//Send message form server to client
public class FileServerAsyncTask extends AsyncTask<Object, Object, Object> {
    private Context context;
    String message;
    public FileServerAsyncTask(Context context, String statusText) {
        this.context = context;
    }
    @Override
    protected Object doInBackground(Object... arg0) {
        // TODO Auto-generated method stub
        Socket socket = null;
        try {

            ServerSocket serverSocket = new ServerSocket(8988);
                //Reading the message from the client
                socket = serverSocket.accept();
                InputStream is = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String number = br.readLine();
                toastmessage = number;
                Log.e("test", "Message received from client is "+number);

                //Multiplying the number by 2 and forming the return message
                String returnMessage;
                returnMessage = "Return message from Server..";//String.valueOf(returnValue) + "\n";

                //Sending the response back to the client.
                OutputStream os = socket.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(os);
                BufferedWriter bw = new BufferedWriter(osw);
                bw.write(returnMessage);
                Log.e("test", "Message sent to the client is "+returnMessage);
                bw.flush();

        }catch (Exception e){
            Log.e("test", "SERVER to CLIENT message sending exception: "+e.getMessage());
        }finally {
            try{
                socket.close();
            }
            catch(Exception e){}
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        Toast.makeText(MainActivity.this, "Message from Client: "+toastmessage, Toast.LENGTH_SHORT).show();
    }

}

}

这是我的WifiP2PBroadCast.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;

public class WifiP2PBroadCast extends BroadcastReceiver{
private WifiP2pManager mManager;
private Channel mChannel;
private MainActivity activity;

public WifiP2PBroadCast(WifiP2pManager manager, Channel channel, MainActivity activity) {
    // TODO Auto-generated constructor stub
    super();
    this.mManager = manager;
    this.mChannel = channel;
    this.activity = activity;
}
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    String action = intent.getAction();
    if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
        // Respond to new connection or disconnections
        mManager.requestConnectionInfo(mChannel, activity);

    } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
        // Respond to this device's wifi state changing
        activity.updateDeviceInfo((WifiP2pDevice) intent.getParcelableExtra(
                WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
    }
}

}

这是AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.suresh.wifi_p2p_demo"
android:versionCode="1"
android:versionName="1.0" >

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-sdk
    android:minSdkVersion="15"
    android:targetSdkVersion="25" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

1 个答案:

答案 0 :(得分:0)

如果您收到消息时出现此错误
您需要移除正在使用的群组才能继续

    mManager.removeGroup(mChannel, null);