24

我能够通过 UDP socket 正确发送我的数据,但是当我收到数据时,它一直在等待接收命令,我不知道是什么原因造成的。请在下面查看我的代码。

我能够在服务器端从 android 设备正确接收数据,但是当我从服务器端向 android 设备发送数据时它没有接收到。但是当我将数据从服务器发送到任何其他客户端(例如 PC 应用程序)时,它会正确接收并显示数据。

class Task implements Runnable {
    @Override
    public void run() {
        try {
            String messageStr = "feed";
            int server_port = 8888;
            InetAddress local = InetAddress.getByName("10.0.2.2");
            int msg_length = messageStr.length();
            byte[] message = messageStr.getBytes();


            DatagramSocket s = new DatagramSocket();
           // 

            DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port);
            s.send(p);//properly able to send data. i receive data to server

            for (int i = 0; i <= 20; i++) {
                final int value = i;
                message = new byte[30000];
                p = new DatagramPacket(message,message.length );
                s.receive(p); //keeps on waiting here but i am sending data back from server, but it never receives
                final byte[] data =  p.getData();;
                try {



                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setProgress(value);
                        imageView.setImageBitmap(BitmapFactory.decodeByteArray(data,0,data.length));
                    }
                });
            }
        }
        catch(Exception ex)
        {

        }
    }
}
4

2 回答 2

27

Eclipse 中的文档:

从此套接字接收数据包并将其存储在参数包中。pack 的所有字段都必须根据接收到的数据进行设置。如果接收到的数据长于数据包缓冲区大小,则将其截断。此方法会一直阻塞,直到收到数据包或超时。

" s.receive(p);" 命令阻塞线程,直到它收到数据或用 setSoTimeout(timeout) 设置的超时结束。

我做了两节课来让我的交流发生。第一个 UDP 服务器:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;

public class UDP_Server 
{
    private AsyncTask<Void, Void, Void> async;
    private boolean Server_aktiv = true;

    @SuppressLint("NewApi")
    public void runUdpServer() 
    {
        async = new AsyncTask<Void, Void, Void>() 
        {
            @Override
            protected Void doInBackground(Void... params)
            {   
                byte[] lMsg = new byte[4096];
                DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
                DatagramSocket ds = null;

                try 
                {
                    ds = new DatagramSocket(Main.SERVER_PORT);

                    while(Server_aktiv)
                    {
                        ds.receive(dp);

                        Intent i = new Intent();
                        i.setAction(Main.MESSAGE_RECEIVED);
                        i.putExtra(Main.MESSAGE_STRING, new String(lMsg, 0, dp.getLength()));
                        Main.MainContext.getApplicationContext().sendBroadcast(i);
                    }
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                } 
                finally 
                {
                    if (ds != null) 
                    {
                        ds.close();
                    }
                }

                return null;
            }
        };

        if (Build.VERSION.SDK_INT >= 11) async.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        else async.execute();
    }

    public void stop_UDP_Server()
    {
        Server_aktiv = false;
    }
}

我将接收到的数据发送到 BroadcastReceiver,然后你可以对数据做任何你想做的事情。

现在我的客户发送数据。在这段代码中,我发送了一个广播,但我认为更改发送到直接 IP 或其他东西的代码是没有问题的。

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;

public class UDP_Client 
{
    private AsyncTask<Void, Void, Void> async_cient;
    public String Message;

    @SuppressLint("NewApi")
    public void NachrichtSenden()
    {
        async_cient = new AsyncTask<Void, Void, Void>() 
        {
            @Override
            protected Void doInBackground(Void... params)
            {   
                DatagramSocket ds = null;

                try 
                {
                    ds = new DatagramSocket();
                    DatagramPacket dp;                          
                    dp = new DatagramPacket(Message.getBytes(), Message.length(), Main.BroadcastAddress, Main.SERVER_PORT);
                    ds.setBroadcast(true);
                    ds.send(dp);
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
                finally 
                {
                    if (ds != null) 
                    {   
                        ds.close();
                    }
                }
                return null;
            }

            protected void onPostExecute(Void result) 
            {
               super.onPostExecute(result);
            }
        };

        if (Build.VERSION.SDK_INT >= 11) async_cient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        else async_cient.execute();
    }

以下是从主类实例化类的方法。

            //start UDP server
        Server = new UDP_Server();
        Server.runUdpServer();

        //UDP Client erstellen
        Client = new UDP_Client();

以及如何与客户端发送消息。

                                    //Set message
                Client.Message = "Your message";
                                    //Send message
                Client.NachrichtSenden();

要停止 UDP_Server,只需将 Server.Server_aktiv 设置为 false。

要设置上面的消息,您还可以编写“setMessage(String message)”方法或类似的东西。

于 2013-10-23T12:18:21.597 回答
6

在这里,在这篇文章中,您将找到在设备之间或同一移动设备中的两个应用程序之间建立套接字的详细代码。

您必须创建两个应用程序来测试下面的代码。

在两个应用程序的清单文件中,添加以下权限

<uses-permission android:name="android.permission.INTERNET" />

第一个应用程序代码:UDP 客户端套接字

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow
        android:id="@+id/tr_send_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="11dp">

        <EditText
            android:id="@+id/edt_send_message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:hint="Enter message"
            android:inputType="text" />

        <Button
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="Send" />
    </TableRow>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/tr_send_message"
        android:layout_marginTop="25dp"
        android:id="@+id/scrollView2">

        <TextView
            android:id="@+id/tv_reply_from_server"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </ScrollView>

</RelativeLayout>

UDPClientSocketActivity.java

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * Created by Girish Bhalerao on 5/4/2017.
 */

public class UDPClientSocketActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mTextViewReplyFromServer;
    private EditText mEditTextSendMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonSend = (Button) findViewById(R.id.btn_send);

        mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
        mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);

        buttonSend.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_send:
                sendMessage(mEditTextSendMessage.getText().toString());
                break;
        }
    }

    private void sendMessage(final String message) {

        final Handler handler = new Handler();
        Thread thread = new Thread(new Runnable() {

            String stringData;

            @Override
            public void run() {

                    DatagramSocket ds = null;
                    try {
                        ds = new DatagramSocket();
                        // IP Address below is the IP address of that Device where server socket is opened.
                        InetAddress serverAddr = InetAddress.getByName("xxx.xxx.xxx.xxx");
                        DatagramPacket dp;
                        dp = new DatagramPacket(message.getBytes(), message.length(), serverAddr, 9001);
                        ds.send(dp);

                        byte[] lMsg = new byte[1000];
                        dp = new DatagramPacket(lMsg, lMsg.length);
                        ds.receive(dp);
                        stringData = new String(lMsg, 0, dp.getLength());

                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (ds != null) {
                            ds.close();
                        }
                    }

                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        String s = mTextViewReplyFromServer.getText().toString();
                        if (stringData.trim().length() != 0)
                            mTextViewReplyFromServer.setText(s + "\nFrom Server : " + stringData);

                    }
                });
            }
        });

        thread.start();
    }
}

第二个应用程序代码 - UDP 服务器套接字

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_stop_receiving"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="STOP Receiving data"
        android:layout_alignParentTop="true"
        android:enabled="false"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="89dp" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/btn_stop_receiving"
        android:layout_marginTop="35dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/tv_data_from_client"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </ScrollView>

    <Button
        android:id="@+id/btn_start_receiving"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="START Receiving data"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="14dp" />
</RelativeLayout>

UDPServerSocketActivity.java

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * Created by Girish Bhalerao on 5/4/2017.
 */

public class UDPServerSocketActivity extends AppCompatActivity implements View.OnClickListener {

    final Handler handler = new Handler();

    private Button buttonStartReceiving;
    private Button buttonStopReceiving;
    private TextView textViewDataFromClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving);
        buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving);
        textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client);

        buttonStartReceiving.setOnClickListener(this);
        buttonStopReceiving.setOnClickListener(this);

    }

    private void startServerSocket() {

        Thread thread = new Thread(new Runnable() {

            private String stringData = null;

            @Override
            public void run() {

                byte[] msg = new byte[1000];
                DatagramPacket dp = new DatagramPacket(msg, msg.length);
                DatagramSocket ds = null;
                try {
                    ds = new DatagramSocket(9001);
                    //ds.setSoTimeout(50000);
                    ds.receive(dp);

                    stringData = new String(msg, 0, dp.getLength());
                    updateUI(stringData);

                    String msgToSender = "Bye Bye ";
                    dp = new DatagramPacket(msgToSender.getBytes(), msgToSender.length(), dp.getAddress(), dp.getPort());
                    ds.send(dp);

                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (ds != null) {
                        ds.close();
                    }
                }
            }

        });
        thread.start();
    }

    private void updateUI(final String stringData) {

        handler.post(new Runnable() {
            @Override
            public void run() {

                String s = textViewDataFromClient.getText().toString();
                if (stringData.trim().length() != 0)
                    textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData);
            }
        });
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_start_receiving:

                startServerSocket();

                buttonStartReceiving.setEnabled(false);
                buttonStopReceiving.setEnabled(true);
                break;

            case R.id.btn_stop_receiving:

                //Add logic to stop server socket yourself

                buttonStartReceiving.setEnabled(true);
                buttonStopReceiving.setEnabled(false);
                break;
        }
    }
}
于 2017-05-04T09:48:47.433 回答