Android Wi-Fi Direct P2P 从服务器向客户端发送数据

标签 android sockets wifi-direct wifimanager wifip2p

我有一个 Android 应用程序,我想在其中使用 Android 的 WiFi Direct P2P 功能在 2 个或更多设备之间发送数据。我的应用程序是基于 Google's WiFi Direct Demo 创建的.问题是,我想将数据从我的服务器(组所有者)发送到客户端。该演示没有显示如何执行此操作。我尝试了以下内容,但不断收到“java.net.UnknownHostException:主机未解析”错误。

我目前做的是:

在 WifiP2pManager.ConnectionInfoListener 接口(interface)中,我实现了 onConnectionInfoAvailalbe,如下所示:

public void onConnectionInfoAvailable(WifiP2pInfo info) {

    if(mInitiatedConnection || mInitiatedDiscover) {
        if (mPeerSelectionDialog != null && mPeerSelectionDialog.isShowing()) {
            mPeerSelectionDialog.dismiss();
            mPeerSelectionDialog = null;
        }

        if (info.groupFormed && info.isGroupOwner) {
            Uri[] uris = getSelectedFiles();
            //send data to clients
            new ServerAsyncTask(getActivity(),info,uris).execute();
        } else if (info.groupFormed) {
          //Ping Server with IP address
            new PingServerAsyncTask(getActivity(),info).execute();

            //Wait for Server to Send data
            new FileServerAsyncTask(getActivity(),mManager,mChannel).execute();
        }

下面是我对三个线程的实现: FileServerAsyncTask(删除了不相关的代码)

public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
    /**
     * @param context
     */
    public FileServerAsyncTask(Context context, WifiP2pManager m, WifiP2pManager.Channel c) {
//intialize
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            ServerSocket serverSocket = new ServerSocket(8988);
            Log.d(MultiImageSelectorFragment.TAG, "Server: Socket opened");
            Socket client = serverSocket.accept();
            Log.d(MultiImageSelectorFragment.TAG, "Server: connection done");
            final File f = new File(Environment.getExternalStorageDirectory() + "/"
                    + context.getPackageName() + "/wifip2pshared/" + System.currentTimeMillis()
                    + ".jpg");

            File dirs = new File(f.getParent());
            if (!dirs.exists())
                dirs.mkdirs();
            f.createNewFile();

            Log.d(MultiImageSelectorFragment.TAG, "server: copying files " + f.toString());
            InputStream inputstream = client.getInputStream();
            copyFile(inputstream, new FileOutputStream(f));
            serverSocket.close();
            return f.getAbsolutePath();
        } catch (IOException e) {
            Log.e(MultiImageSelectorFragment.TAG, e.getMessage());
            return null;
        }
    }

    /*
     * (non-Javadoc)
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(String result) {
      //Do stuff with data..

    }

ServerAsyncTask(删除了空代码/初始化程序,因为它不相关)

public static class ServerAsyncTask extends AsyncTask<Void, Void, String> {

    public ServerAsyncTask(Context context, WifiP2pInfo info, Uri[] uris) {

    }

    @Override
    protected String doInBackground(Void... params) {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(8988);
            Log.d(MultiImageSelectorFragment.TAG, "Server: Socket opened");
            boolean serverIsRunning = true;

            while(serverIsRunning) {
                Socket client = serverSocket.accept();
                        String addr = client.getInetAddress().toString();
                sendPictures(addr);
            }
            serverSocket.close();

            return null;
        } catch (IOException e) {
            Log.e(MultiImageSelectorFragment.TAG, e.getMessage());
            return null;
        }finally {

        }
    }

    private void sendPictures(String remoteAddress) {
        Uri uri = mURIs[0];
        Log.d(MultiImageSelectorFragment.TAG, "Intent----------- ");
        Intent serviceIntent = new Intent(context, FileTransferService.class);
        serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
        serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
        //serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, mInfo.groupOwnerAddress.getHostAddress());
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, remoteAddress);
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
        context.startService(serviceIntent);
    }     

}

PingServerAsyncTask(删除了空代码/初始化程序,因为它不相关)

public static class PingServerAsyncTask extends AsyncTask<Void, Void, String> {


    public PingServerAsyncTask(Context context, WifiP2pInfo m) {

    }

    @Override
    protected String doInBackground(Void... params) {


            String host = mInfo.groupOwnerAddress.getHostAddress();
            Socket socket = new Socket();
            int port = 8988;
            int SOCKET_TIMEOUT = 5000;
            try {
                Log.d(MultiImageSelectorFragment.TAG, "Opening client socket - ");
                socket.bind(null);

                socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
                Toast.makeText(context, "server:"+host + "me:"+socket.getLocalAddress(), Toast.LENGTH_LONG).show();
                Log.d(MultiImageSelectorFragment.TAG, "Client socket - " + socket.isConnected());

            } catch (Exception e) {
                Log.e(MultiImageSelectorFragment.TAG, e.getMessage());

            } finally {
                if (socket != null) {
                    if (socket.isConnected()) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // Give up
                            e.printStackTrace();
                        }
                    }
                }
            }
        return null;
    }




}

代码背后的想法是: 群主(服务器)

  1. 打开服务器线程并等待客户端ping
  2. (*)当客户端“ping”时,服务器现在知道客户端的 IP 地址(client.getInetAddress().toString();在 ServerAsyncTas 中),因此它可以将数据发送到客户端。所以服务器向客户端发送数据,并等待另一个客户端连接

不是组所有者(客户端)

  1. 在连接上,根据 PingServerAsyncTask“ping”群组所有者(因为我们知道群组所有者地址)。
  2. Ping 后启动 FileServerAsyncTask 并等待服务器发送数据。

问题是,当服务器尝试在标记为 (*) 的步骤中发送数据时,我得到一个 java.net.UnknownHostException: Host is unresolved: 异常。我不明白为什么我会得到那个异常(exception)?我使用的IP地址是我刚从客户端ping服务器得到的IP地址,所以它应该是正确的?不确定是什么问题?

(注意:我没有包含 FileTransferService.class 实现,因为它是 Google WifiDirect 演示中那个的精确副本,因此可以在第一段的链接中找到)

最佳答案

您应该使用套接字输入和输出流在客户端和服务器之间进行通信。

服务器端连接后:

dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
dataInputStream = new DataInputStream(clientSocket.getInputStream());

发送短信:

dataOutputStream.writeUTF(message);
dataOutputStream.flush();

我在这里回答了类似的问题:Peer to peer data sharing using Wi-Fi direct

如果这没有帮助,请告诉我。 祝你好运。

关于Android Wi-Fi Direct P2P 从服务器向客户端发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41134703/

相关文章:

java - 如何为listView中的特定项目添加点击

c - 以编程方式查找阻止端口创建的应用程序

android - WifiP2pInfo.groupOwnerAddress.getHostAddress() IP 错误

android - JellyBean 上的 WiFi-Direct,WPA 请求者搞砸了

android - 是否可以连接两个或多个 WiFi Direct 组?

android - 没有找到此应用程序和葫芦版本组合的测试服务器。重新创建测试服务器

java - 如何在谷歌地图上添加和检索地点

android - 如何浏览文件并通过蓝牙将其发送到连接的设备?

android - 再次恢复应用程序时如何不重新加载webview?

java - 客户端关闭后保持套接字服务器打开