为什么我android UDP通信 只能发信息接收不到信息。请大神帮忙

主进程

import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class YuntuActivity extends ActionBarActivity implements OnClickListener {

private TextView adSpeed;
private TextView reSpeed;
private TextView reTxt;
private Button btnHeadCar;
private Button btnAgree;
private Button btnApply;
private Button btnStart;
private Button btnExit;

//自定义变量
private String remoteIP = null;
private int rePort = 0;
private int loPort = 0;
private UDPThread reTxtThread = null;
private UDPThread adSpeedThread = null;
private UDPThread reSpeedThread = null;
private String sendStr = null;//发送的字符串
private String receStr = null;


Handler mhander = new Handler() {

    public void handleMessage(Message msg) {

        Bundle bundle =new Bundle();
        bundle = msg.getData();
        receStr = bundle.getString("info");
        reTxt.setText(receStr);
    }
};

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

    //初始化UI
    initUI();

    //初始化
    init();

    reTxtThread = new UDPThread(mhander);

}

private void init() {
    remoteIP = "172.22.130.124";
    rePort = 8801;
    loPort = 8805;
}

//初始化UI
private void initUI() {
    adSpeed =(TextView)findViewById(R.id.AdSpeed);
    reSpeed =(TextView)findViewById(R.id.ReSpeed);
    reTxt =(TextView)findViewById(R.id.reTxt);
    btnHeadCar =(Button)findViewById(R.id.button1);
    btnAgree =(Button)findViewById(R.id.button2);
    btnApply =(Button)findViewById(R.id.button3);
    btnStart =(Button)findViewById(R.id.button4);
    btnExit =(Button)findViewById(R.id.button5);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    //点击  同意入队  按钮
    case R.id.button1:
        sendStr = "you can join in flownteam.";
        if(!sendStr.trim().equals("")) {
            reTxtThread.sendData(sendStr);
        }
        break;  

        //点击 申请入队按钮
    case R.id.button2:
        sendStr = "Can I join in?";
        if(!sendStr.trim().equals("")) {
            reTxtThread.sendData(sendStr);
        }
        break;  

        //点击申请离队按钮
    case R.id.button3:
        sendStr = "Can I exit?";
        if(!sendStr.trim().equals("")) {
            reTxtThread.sendData(sendStr);
        }
        break;  

        //点击开始监听按钮
    case R.id.button4:
        reTxtThread.setReomteIP(remoteIP);

        reTxtThread.setRePort(rePort);

        reTxtThread.setLoPort(loPort);

        boolean connResult = reTxtThread.connectSocket();

        if(connResult) {
            Toast.makeText(getApplicationContext(), "链接建立完毕!", Toast.LENGTH_SHORT).show();
        }

        break;          

        //点击关闭监听按钮  
    case R.id.button5:
            reTxtThread.disConnectSocket();
            Toast.makeText(getApplicationContext(), "链接已经关闭!", Toast.LENGTH_SHORT).show();

        break;
    default:
        break;
    }
}

}

子线程:接收和发送UDP包
package com.example.cqput_yuntu2;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;

public class UDPThread implements Runnable {

// 定义变量
private TextView rTextView = null;
private String reomteIP = null;
private int rePort = 0;
private int loPort = 0;
private Thread rThread = null;
private static String CHARECTER = "UTF-8";
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

// 接收
private byte[] rBuffer = new byte[1024];
private DatagramSocket rSocket = null;
private DatagramPacket rPacket = null;
private String rStr = null;

// 发送
private DatagramSocket sSocket = null;
private DatagramPacket sPacket = null;
private byte[] sBuffer = new byte[1024];
public Handler mhandler;

public UDPThread(Handler handler) {
    mhandler = handler;
}

@Override
public void run() {
    // 开始接收数据
    Looper.prepare();
    if (Thread.currentThread() == rThread) {
        System.out.println("------jieshouqian");
        rStr = receiveData();
        System.out.println("------jieshouhou");
        Message toMain = mhandler.obtainMessage();

        Bundle bundle = new Bundle();
        bundle.putString("info", rStr);
        toMain.setData(bundle);
        mhandler.sendMessage(toMain);

    }
    ;
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

// 开始接收数据
private String receiveData() {
    try {
        ByteArrayInputStream bais = new ByteArrayInputStream(rBuffer);
        DataInputStream dis = new DataInputStream(bais);
        if (rSocket == null) {
            rSocket = new DatagramSocket(8805);
        }
        if (rPacket == null) {
            rPacket = new DatagramPacket(rBuffer, rBuffer.length);
        }
        System.out.println("----rece");
        rSocket.receive(rPacket);
        System.out.println("------receHou");
        rStr = dis.readUTF().trim();
        System.out.println("------jieBeg");
        rStr = String.format("[%s:%d//%s]%s", rPacket.getAddress()
                .getHostAddress(), rPacket.getPort(), sdf
                .format(new Date()), rStr);

        return rStr;
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("-----------------recvdata error:"
                + e.getMessage());
    }
    return null;
}

// 建立连接
public boolean connectSocket() {
    boolean result = false;

    // 开启一个新的线程
    startThread();
    System.out.print("监听线程开启");
    result = true;

    return result;
}

// 关闭连接
public void disConnectSocket() {
    if (rSocket != null) {
        rSocket.close();
        rSocket = null;
    }

    if (rPacket != null) {
        rPacket = null;
    }

    // 关闭线程
    stopThread();
}

// 关闭线程
private void stopThread() {
    if (rThread != null) {
        rThread.stop();
        rThread = null;
    }
}

// 开启新的线程
private void startThread() {
    if (rThread == null) {
        rThread = new Thread(this);
        rThread.start();
    }
}

// 开始发送数据
public void sendData(String sendStr) {

    try {
        // 包装数据
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);
        dos.writeUTF(sendStr);
        sBuffer = baos.toByteArray();
        if (sSocket == null) {
            sSocket = new DatagramSocket();
        }
        if (sPacket == null) {
            sPacket = new DatagramPacket(sBuffer, sBuffer.length,
                    InetAddress.getByName(reomteIP), rePort);
        }
        sSocket.send(sPacket);
        sSocket.close();
        sSocket = null;
        sPacket = null;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        sSocket.close();
        sSocket = null;
        sPacket = null;
        System.out.println("senddata error:" + e.getMessage());
    }
}

public void setReomteIP(String reomteIP) {
    this.reomteIP = reomteIP;
}

public void setRePort(int rePort) {
    this.rePort = rePort;
}

public void setLoPort(int loPort) {
    // this.loPort = loPort;
}

}

2个回答

remoteIP = "172.22.130.124";
rePort = 8801;
loPort = 8805;
这IP应该是Internet上的某个主机吧,若手机与其不在同一局域网中(无论是3、4G还是连接热点,都要至少经过一层网关才能接入Internet,而网关一般都会对局域网内设备有保护。
这里你开启的8801监听,默认情况下只有局域网内设备能访问它。除非你使用该端口向Internet上的主机发送消息,网关在将该消息转发出WAN口时,会为你临时打开一个端口映射,此时该消息的目标主机才可以在外网访问你开的这8801端口。更详细的原理,可以搜索“NAT穿透”。
简言之,在局域网中使用UDP与外网主机双向通信,需要使用同一个端口进行收发,且得先使用该端口向外网主机的某端口发消息,才能收到该主机相应端口发的消息。
另外,代码中收到数据包时解析也有问题,rStr = dis.readUTF().trim();收到的数据包大小是不固定的,而这里直接使用之前建立的输入流,读取整个rBuffer的数据,是不应该的。

补充下,刚才这句话说的不准备:除非你使用该端口向Internet上的主机发送消息,网关在将该消息转发出WAN口时,会为你临时打开一个端口映射,此时该消息的目标主机才可以在外网访问你开的这8801端口。
网关在打开端口映射时,通常在WAN口开的端口并非与LAN主机的端口一致。即LAN主机开个8801端口,向Internet的主机发消息,网关在转发时开了个端口9000。将UDP消息中的端口改为9000,转发出去。Internet上的主机接收到的UDP消息,其中的端口不是8801,而是9000。其若想向LAN主机回消息,目的端口不能用8801,而用9000。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
微信开放,能接收消息不能发送消息
接收的消息: 123456789 即 ToUserName开发者微信号FromUserName发送方帐号(一个OpenID)CreateTime消息创建时间 (整型)MsgType消息类型,eventEvent事件类型,subscribe(订阅)、unsubscribe(取消订阅) 被动回复: 12345678 参数是否必须描述ToUserName是接收方帐
安卓UDP接收数据 经常失败
WIFI芯片发送广播UDP数据给手机,经常出现安卓UDP接收数据 经常失败 解决方法: 1)WifiManager.MulticastLock 对象lock    失败,还是不行 一、有的手机不能直接接收UDP包,可能是手机厂商在定制Rom的时候把这个功能给关掉了。 1、可先在oncreate()方法里面实例化一个WifiManager.M
TCP UDP多机通信无法接收到数据的问题
TCP UDP调试注意事项 一般如果是使用localhost和127.0.0.1这种做server端IP的情况,服务器与客户一般是在一个主机上进行了,这个时候做调试一般不会出现什么问题。但是不同的机器做主机与服务器的时候就不一样了。比方说Android与电脑,电脑与电脑通信会出现各种奇怪的问题。出现这种问题一般可以从以下几种途径找问题: (1)电脑上是不是开了防火墙,如果开了就关掉 (2)电
C#winform UDP通信 发送和接收信息
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text;
关于android组播通讯只能收到本机消息的问题
答案是Android为了减少耗电,默认是不接收组播消息的。想要接收,必须把这个开关打开。 打开方法:↓
如何解决UDP外网无法接收数据
如何解决UDP外网无法接收数据标题可能不能够专业,但是就是这遇到问题的表现。通过UDP开发一个小程序,本来在局域网内都测试通过。部署到外网服务器上就出现问题了。本来可以接收服务器的UDP回复的,现在统统接收不到了。网上找查了原因有很多,也带了很多名词: UDP打洞,心跳包 等等。查了又看,算是明白一点了,但是绕来绕去最终目的也就是外网也能想局域网一样能够接收普通的UDP包数据。这个问题我是第一次遇到
关于android组播DatagramPacket不能正常接收问题
做到关于组播的问题时,明明手机发送电脑的java客户端能接收,但电脑发送的组播一直接收不了. 而手机自己发送的组播自己能接收....... 在网上找了很多资代码料,都说要Android为了省电把接收组播关了要手动打开 代码如下: WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE
安卓真机上UDP程序收不到PC机数据包的解决方法
最近在写安卓UDP通信程序时遇到这个问题,就是在安卓模拟器上可以实现收发,但是放到真机上就只能发收不到PC机发来的数据。在网上查了一些资料,发现有很多朋友也遇到这个问题,都没有非常明确的解决方法,我经过尝试终于在真机上收到了PC机发的数据,跟大家分享一下。我用的是eclipse开发环境,安卓虚拟机为2.2版本。为方便讲解,先贴几张图:                图一 安卓模拟器界面
关于UDP向本机端口发送数据报但是接收不到数据的问题
用UDP数据报发送数据给本机,数据可以发出去,但是服务端(本机)却接收不到任何数据,刚接触网络,请指教! 服务器端: SOCKET  server_socket_udp; sockaddr_in server_address_udp,from_address_udp; char server_data[20]="你好"; server_socket_udp=socket(AF_INET,
为什么QUdpSocket只能收一次?原来是因为
当你定义了QUdpSocket对象并且连接了readyRead信号和自定义的接收处理槽: connect(udpsocket,SIGNAL(readyRead()),this,SLOT(udpreceive())); 接受处理槽: void MainWindow::udprecerive() { qDebug() } 你会发现只能触发一次,原因是你并没有提取掉上次收到的内容,如果你把
Node.js UDP服务器无法收到客户端消息
Node.js UDP服务器无法收到客户端消息          在《Node.js开发实战详解》这本书的第四章里,在架设Node.js服务器后,运行客户端程序,服务器无法收到消息。server.jsvar dgram = require('dgram'); var server = dgram.createSocket('udp4'); server.on('listening', funct
Socket编程 (连接,发送消息) (Tcp、Udp) ,这个是同步,跟上一篇差不多
Socket编程 (连接,发送消息) (Tcp、Udp)  本篇文章主要实现Socket在Tcp\Udp协议下相互通讯的方式。(服务器端与客户端的通讯)   1.基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息。   使用Tcp协议通讯需要具备以下几个条件:     (1).建立一个套接字(Socket)     
GCDAsyncUdpSocket 收不到广播包?
IOS开发中,使用 GCDAsyncUdpSocket接收广播包,折腾半天没有反应。其实很简单, bind port时不要指定 interface!  [mGCDAsyncUdpSocket bindToPort:0  error:&error];
QT下udpsocket一段时间接收不到数据的问题
最近在做一个项目  采用UDPSOCKET进行数据的传输,发现在一段时间后,UDP接收不到数据了,找了很久的资料 才发现解决该问题的方法,估计不是最好的。代码如下: #include "mainwindow.h" #include "ui_mainwindow.h" #include MainWindow::MainWindow(QWidget *parent) : Q
java Udp实现简单地发送接收信息
在理解tcp的基础上你会发现udp的高效,简单地发送接收消息带你开始理解Udp
关于Android中接收不到组播信息
最近在做局域网内群组短消息功能时,发现有的设备不能接收组播信息,或者亮屏的时候可以接收组播消息,灭屏之后却接收不到组播信息,在网上找了很多资代码料,都说要Android为了省电把接收组播关了要手动打开,参考如下前辈的博客: http://blog.csdn.net/cxlmax/article/details/7864993 要想打开组播功能,有以下几个步骤: 在Ma
UDP信息接收与发送
转载:http://www.cnblogs.com/sunev/archive/2012/08/08/2627247.html 一、摘要    总结基于C#的UDP协议的同步通信。   二、实验平台    Visual Studio 2010   三、实验原理    UDP传输协议同TCP传输协议的区别可查阅相关文档,此处不再赘述。   四、实例  4.1 采用socke
udp 传输,可解决中文不能正确传输,乱码问题
刚开始,按JDK 里的例子写, // join a Multicast group and send the group salutations ... String msg = "Hello"; InetAddress group = InetAddress.getByName("228.5.6.7"); MulticastSocket s = new MulticastSo
关于Qt中Udp通信过程中的接收数据部分注意
Communication::Communication(Global *a) { varcom=a; msg=new QMessageBox(); udpclient=new QUdpSocket(this); // QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
Qt下UDPSocket一段时间后接收不到数据的问题
Qt下UDPSocket一段时间后接收不到数据的问题
C#编写的UDP收发数据 单独的接收数据程序可以用 但是写的接收和发送的不好使
如题 求大神指教 如何用C#发送结构体
udp发送和接收消息,服务端
1、使用UDPClient发送(send)和接收(recive): UdpClient ServerSender;     private int sendUDP(Message msg) {         int responcecode = 0;         //动态获取Ip地址         IPHostEntry ihe = Dns.GetHostByName(D
linux udp 客户端recvfrom,一直没有数据接收,谁能帮看看这代码哪里出了问题了????
void* StartDiscoveryThread(void *arg) { int so_broadcast=1; struct sockaddr_in toAddr; //客户端的网络地址。 struct sockaddr_in serverAddr; //服务器端的网络地址。 char inBuff[DD_BUFF_LEN]; int sockaddrLen = 0; in
android中关于udp发送、接收的一些重点总结
最近做了一个关于udp的项目,分为移动端和服务器端,移动端用来给服务器发送数据同时接收服务器返回的数据,服务器当然是接收客户端数据了,然后返回一定的信息。期间遇到了很多问题,但最后还是解决了,所以想和他人分享一下下,希望可以帮到一些开发的朋友。       做这个项目时,在网上也是查了一些资料,发现很多朋友在客户端接收服务器返回数据时出了问题,发送几乎没有什么问题。       这些问题的发生
Android手机接收不到UDP报文
问题: 同一套程序在中兴手机和华为手机上可以接收到UDP广播报文,但在HTC手机上却接收不到? 问题原因:(仅猜测而已,未经过验证) 手机开启UDP广播功能不仅耗电,而且占用系统资源。可能有些手机厂家默认把这个功能给关掉了, 你若想要用手机来发送接收UDP报文,得先申请,才能使用这个功能。 具体如何申请和释放: 1、可先在oncreate()方法里面
UDP通讯接收案例(组播方式)
1.通讯类: namespace AddMyUtility {     public class UDPClientClass     {         public UDPClientClass(string groupIP, int Port, int timeOut)         {             _UdpClient = new UdpClient(Port)
JAVA 网络编程(5) SOCKET UDP 单播和组播,以及组播其他机器收不到报文的解决方法
UDP既可以单播也可以组播 一,单播 单播的过程为 发送方: InetAddress destAddr = InetAddress.getByName("192.168.4.199");// 发送的目的地址 int targetPort = 3001; // 发送的目的端口 DatagramSocket socket = new DatagramSocket(); byte[] b
关于java Udp收发数据异常的笔记
笔者前段时间在android上用到udp相关的技术,一般来说无非就是接收与发送两个功能。于是笔者就分别开了两条线程分别创建一个DatagramSocket 去负责接收数据与发送数据。岂料出现了发送或接收不能正常进行的错误~~~然后在网上找到原因了:就是把接收和发送数据的操作都在同一个DatagramSocket上进行。 笔者试了一下,果然一切正常进行~如果读者发生了笔者类似的错误,而且又
【脱光】请一个女孩子吃饭后,发短信不回了
我想追一个女孩子,请她吃饭后,发短信就不回了。我该怎么样?  一个追,一个跑,似乎是一种没完没了的游戏。如果你的目的是要把女孩抱回去,最好换一种方法。第一步是要交往自然,不能有刻意追求举动,也不可以暴露爱意,最好是想都不要想谈恋爱的事情。但是暗地里要创造一些单独在一起的机会,这个时候要温柔,要散发魅力,这样就差不多了只要你们常在一起,无话不谈基本上就算搞定了。反正第一要诀就是不要让她开始跑 就是
MFC的UDP接收端通信
由于之前一直在弄TCP的MFC程序编写,导致对UDP的MFC情况下的编写不太清楚。摸索了一天,终于知道了UDP的一些情况以及注意事项。 1、UDP介绍 UDP是不保证发送的数据都被接收到,即一端只负责发,另一端是否接收到它都不管。为此,UDP一般情况下用于数据量比较大、但对每一次数据的是否都接收到不做要求。而TCP是可以保证每一次数据都被接收到。总之,根据运用情况而定。(个人理解,具体详解请自
在QT下的基于UDP协议的消息收发程序
前段时间学了Linux高级编程,其中网络编程部分中有一个基于Udp/Tcp的聊天编程给我感觉蛮有趣的,但是只能在命令行收发信息还是显得单调,远远没有图形界面的方便和美观。有没有办法做的漂亮一点呢?强大又低调的QT可以做到这一点。 QT为提供了强大的网络编程接口类供我们使用。QAbstractSocket类提供所有的socket(套接口)类型的公共功能。QAbstractSocket是QUdpSo
UDP数据报通信 使用DatagramSocket发送、接收数据(Socket之UDP套接字)
http://book.51cto.com/art/201203/322540.htm 17.4.2 使用DatagramSocket发送、接收数据(1) Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,Da
QUdpSocket收不到回复及分析
QT中使用QUdpSocket发送数据给服务器,然后通过readyread信号读取回复。init: udp=new QUDPSocket() connect(udp,SIGNAL(readyread()),this,SLOT(processread()));work: udp->writedatagram实际情况是:数据能够发送出去,服务器返回的数据却无法触发readyread信号。实验后,如下代码
C#使用UdpClient发送和接收UDP数据示例
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.W
UDP广播(可用于本机进程间通信)
一、有的手机不能直接接收UDP包,可能是手机厂商在定制Rom的时候把这个功能给关掉了。 1、可先在oncreate()方法里面实例化一个WifiManager.MulticastLock 对象lock;具体如下: WifiManager manager = (WifiManager) this .getSystemService(Context.WIFI_S
用udp协议通讯示例 UDP实现广播接收回复的例子
一、绪言 udp是一种面向非连接,不可靠的通讯协议,相对于tcp来说,虽然可靠性不及,但传输效率较高。所以在网络上仍有很大的用途。这几日需要了解下udp通讯的过程,上网发现这方面的资料还挺少。于是仔细的翻找了下msdn,基本上搞清楚了udp通讯的过程。做了一个测试的例子。希望对大家有帮助。 二、udp的通讯过程 server端: open a socket(socket)--->
基于Android的UDP自动发现(接收与发送)
TCP和UDP的区别: TCP(Transimission Control Protocol)即 传输控制协议:是面向连接的协议, 强调稳定可靠的连接,建立连接“三次握手”,断开连接需要“四次分手”,现常用于网络间视频与语音通话,及相应的网络间可靠的信息流通。 UDP(User Datagram Protocol)即 用户数据报协议:是面向报文的协议,两端无需建立连接即可传输数据,速度和效率都
android之同一wifi下两台设备通过UDP进行通讯
参考文章地址:http://www.cocoachina.com/android/20171016/20806.html前端布局如下:Activity中的全部代码,其中使用了butterknife实现View中控件的实例化。package com.example.a260219.myapplication; import android.os.Bundle; import android.os....
C# UDP接收不同端口的数据报文
在unity中使用UDP进行数据的交互,建立C/S模式,两个客户端和一个服务端。两个客户端使用不同的端口往服务端发送数据,服务端根据收到的数据进行处理和判断,控制服务端的显示。 说明:两个客户端连接的是Kinect V2,需要将检测到的人体的数据信息发送到服务端进行系统数据的整体显示。指定的消息协议是ClientID|index|PosLeft|Left_S|PosRight|Right_S|A
VB实现UDP通信,并对接收到的数据进行简单处理!
用VB实现UDP通讯,有客户端和服务器端。 并且对接收到的数据进行简单处理,为了便于和上位机通讯,并在VB界面上显示处理后的结果。
相关热词 c#怎么调用api接口 c# 调用mstsc c#扩展函数 c#向上转换向下转换 c#chart直方图叠加 c# 添加body样式 c# 调用接口 c#高德地图经纬度查询 c# 测试并发 c# 取操作系统