Android studio 中使用 DatagramSocket 进行UDP 数据 接收,对 端口 绑定,绑定失败

Android中使用 DatagramSocket 进行UDP数据发送接收,对端口绑定,绑定失败

在使用Android studio开发app的过程中,使用UDP的类DatagramSocket 进行数据的发送和接收,出现一个问题---- 在使用Android studio自带的安卓模拟器和从网络上下载的安卓模拟器进行模拟数据的发送和接收,往往只能将数据发送出去,但是接收不到,本文使用的接收代码如下:

  //接收消息代码
   DatagramSocket     socket = new DatagramSocket(51280);
   try {
           while(!socket.isClosed()){
               byte[] data = new byte[4*1024];
               DatagramPacket packet =new DatagramPacket(data,data.length);
               socket.receive(packet);
               String msg= new String(packet.getData(),packet.getOffset(),packet.getLength());
               notifyMain(1,msg);
               Log.d(TAG,"\n收到的消息为:"+msg);
               Log.d(TAG,DateUtil.getNowDateTime());
           }
           System.out.println("循环体执行结束···");
       } catch (Exception e) {
           e.printStackTrace();
           if(!socket.isClosed()){
               notifyMain(0,"未接收到消息");
           }
       }finally {
           if(socket!=null && socket.isClosed() == false) {
               socket.close();
              System.out.println("------->>>>>>> 关闭了 2 socket");
           }
       }

分析

问题出现在下面的代码里,

   DatagramSocket     socket = new DatagramSocket(51280);

在进行端口绑定时,发现在模拟器里面app发送消息或接收消息的实际端口并不是自己定义的端口,而是模拟器随机分配给app的一个端口,导致接收数据时,发送端每次都必须根据当前app端口进行调整。

解决办法

这时候需要你找一个真实的手机安装app,才能成功的绑定指定的端口,端口才不会随机分配!

原因分析

在使用模拟器的时候,能看到一个类似真机的手机,由于是用软件虚拟出来的手机,这个虚拟出来的手机和真实的手机还不一样。模拟器里面app发送消息时的流程是:手机app---->模拟器---->电脑—>外部软件 (接收消息的过程相反)。出于安全原因或者端口占用的原因,模拟器就将你定义的端口给隐藏起来了,然后使用它给你分配的端口进行数据的传输或接收,这个时候在外部软件看来,你发送消息的端口就不是你自己定义的端口,因此接收消息时也必须使用模拟器分配给你的那个端口。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言,可以使用以下代码将UDP套接字绑定到随机端口: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define MAX_BUFFER_SIZE 1024 int main() { int sockfd; struct sockaddr_in server_addr; // 创建套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("Error in socket"); exit(1); } // 设置服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到任意可用的本地IP地址 server_addr.sin_port = 0; // 设置端口为0,表示随机选择一个可用端口 // 绑定套接字到服务器地址 if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("Error in bind"); exit(1); } // 获取绑定的随机端口号 struct sockaddr_in bound_addr; socklen_t bound_addr_len = sizeof(bound_addr); if (getsockname(sockfd, (struct sockaddr*)&bound_addr, &bound_addr_len) < 0) { perror("Error in getsockname"); exit(1); } printf("Bound to random port: %d\n", ntohs(bound_addr.sin_port)); // 进行其他操作... // 关闭套接字 close(sockfd); return 0; } ``` 在上述示例,我们创建了一个UDP套接字,并将其绑定到INADDR_ANY(表示绑定到任意可用的本地IP地址)和端口号0(表示随机选择一个可用端口)。通过调用bind函数,我们将套接字绑定到随机端口。 为了获取绑定的随机端口号,我们使用getsockname函数,并传递一个用于存储获取的地址信息的结构体(bound_addr)。 请注意,由于是随机选择的端口,因此每次运行代码时,可能会获得不同的随机端口号。 在实际应用,你可以根据需要修改代码,以便在绑定随机端口后执行其他操作,如发送或接收数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值