首页 > 其他分享 >AndroidStudio扫描局域网下的ESP32CAM并获取IP地址

AndroidStudio扫描局域网下的ESP32CAM并获取IP地址

时间:2024-03-05 20:02:10浏览次数:25  
标签:ESP32CAM addr ESP dest ip AndroidStudio TAG IP地址 new

大概想法如下:

 

在ESP32CAM端直接下载示例代码udp_server这个历程,修改默认的WIFI和密码,启动之后会输出如下结果

 由此我们知道了UDP的地址和端口IP地址为192.168.2.3,端口为3333

此时我们使用小工具NetAssist.exe来测试,选择UDP协议之后向ESP32CAM的地址发送广播,如下图所示

 此时我们的ESP32CAM控制台则会输出如下相关信息

 说明设备已经收到了广播的UDP数据

之后我们需要自己在AndroidStudio上编写代码,以广播我们自己需要的UDP数据

首先在页面创建一个按钮StartStream,之后写入按钮的回调函数,执行以下代码即可做到广播UDP数据

至于为啥是192.168.2.255,是因为需要广播而不是单播,如果是单播,你需要指定IP地址,如果你需要扫描192.168.2.xxx下的所有设备,你写成192.168.2.255就可以广播了

//预定义变量
private static final String BROADCAST_IP = "192.168.2.255"; // 广播地址
private static final int BROADCAST_PORT = 3333; // 你的广播端口

//写在onCreate中
StartStream.setOnClickListener(v -> {
    sendBroadcastMessage("NBQS_IPCAM");
});

//定义一个发送函数
public void sendBroadcastMessage(String message) {
    new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    DatagramSocket socket = new DatagramSocket();
                    InetAddress inetAddress = InetAddress.getByName(BROADCAST_IP);

                    byte[] buffer = message.getBytes();
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, inetAddress, BROADCAST_PORT);

                    socket.send(packet);
                    socket.setBroadcast(true);
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

  这样就可以在该局域网内部广播UDP数据,当ESP32CAM收到特定的数据之后则会返回设备名称,ESPCAM端UDP的回复部分代码如下

static void udp_server_task(void *pvParameters)
{
    char rx_buffer[128];
    char addr_str[128];
    int addr_family = (int)pvParameters;
    int ip_protocol = 0;
    struct sockaddr_in6 dest_addr;
    static struct sockaddr_in udp_client_addr;

    ESP_ERROR_CHECK(esp_netif_init());

    while (1) {

        if (addr_family == AF_INET) {
            struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
            dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
            dest_addr_ip4->sin_family = AF_INET;
            dest_addr_ip4->sin_port = htons(PORT);
            ip_protocol = IPPROTO_IP;
        } else if (addr_family == AF_INET6) {
            bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un));
            dest_addr.sin6_family = AF_INET6;
            dest_addr.sin6_port = htons(PORT);
            ip_protocol = IPPROTO_IPV6;
        }

        int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
        if (sock < 0) {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket created");

        int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
        if (err < 0) {
            ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
        }
        ESP_LOGI(TAG, "Socket bound, port %d", PORT);

        struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
        socklen_t socklen = sizeof(source_addr);

        while (1) {
            ESP_LOGI(TAG, "Waiting for data");
            int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
            // Error occurred during receiving
            if (len < 0) {
                ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
                break;
            }
            // Data received
            else {
                // Get the sender's ip address as string
                if (source_addr.ss_family == PF_INET) {
                    inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
                } else if (source_addr.ss_family == PF_INET6) {
                    inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
                }

                 // 设置目标地址和端口  
                memset(&udp_client_addr, 0, sizeof(udp_client_addr));  
                udp_client_addr.sin_family = AF_INET;  
                udp_client_addr.sin_port = htons(3333); // 替换为你想要发送到的端口  
                udp_client_addr.sin_addr.s_addr = inet_addr(addr_str); // 替换为你想要发送到的 IP 地址

                rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string...
                ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
                ESP_LOGI(TAG, "%s", rx_buffer);

                if(!strncmp(rx_buffer,"NBQS_IPCAM",10)){
                    ESP_LOGE(TAG, "From IPCAM UC");

                    char DeviceInfo[20] = "NBQS_IPCAM_00000001";

                    int err = sendto(sock, DeviceInfo, 20, 0, (struct sockaddr *)&udp_client_addr, sizeof(udp_client_addr));
                    if (err < 0) {
                        ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
                        break;
                    }
                }else{
                    ESP_LOGE(TAG, "Dont send");
                }  
            }
        }

        if (sock != -1) {
            ESP_LOGE(TAG, "Shutting down socket and restarting...");
            shutdown(sock, 0);
            close(sock);
        }
    }
    vTaskDelete(NULL);
}

之后在Android Studio中监听UDP返回的数据,在处理返回的数据的时候ESPCAM的IP地址也会同时被获取到其处理函数如下:

public void onBroadcastReceive() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("UDP_Server", "Begin");
                while (true) {
                    try {
                        // 创建接收数据报套接字并将其绑定到本地主机上的指定端口
                        DatagramSocket datagramSocket = new DatagramSocket(BROADCAST_PORT);
                        byte[] buf = new byte[1024];
                        final DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
                        datagramSocket.receive(datagramPacket);

                        InetAddress ip = datagramPacket.getAddress();
                        String ipStr = ip + "";

                        String ip_new = ipStr.substring(1, ipStr.length());

                        //过滤掉自身IP
                        if(!(!localIp.equals("") && localIp.equals(ip_new))) {
                            // 获取内容
                            String Content = new String(datagramPacket.getData(),0, datagramPacket.getLength());
                            Log.d("UDP_Server", "From:" + ip_new + "  Content:" + Content);

                            if(Content.substring(0, 10).equals("NBQS_IPCAM")){
                                Log.d("UDP_Server", "符合");
                                //判断原有数组中是否有新的数组
                                if (!MainActivity.this.IpCameraIp.contains(ip_new)) {
                                    MainActivity.this.IpCameraName.add(Content);//将搜索到的蓝牙名称和地址添加到列表。
                                    MainActivity.this.IpCameraIp.add(ip_new);//将搜索到的蓝牙地址添加到列表。

                                    //构建数据格式更新到ListView
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("ico", R.drawable.icon_video);
                                    map.put("name", Content);
                                    map.put("ssid", ip_new);
                                    MainActivity.this.mIpCameraListData.add(map);

                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            MainActivity.this.mIpCameraSimpleAdapter.notifyDataSetChanged();
                                        }
                                    });
                                }
                            }
                        }
                        datagramSocket.close();

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

在上述代码中,我使用了Android Studio中的ListView来展示数据,相关的展示请自行查询数据更新代码,mIpCameraListData中存放的就是设备名称和IP地址

MainActivity.this.mIpCameraSimpleAdapter.notifyDataSetChanged();就是ListView的数据集,如果你不需要,删除即可。

执行sendBroadcastMessage之后,如果发送的数据是NBQS_IPCAM,则Android Studio会收到来自于ESP32CAM发送回的数据,并且保存到mIpCameraListData

标签:ESP32CAM,addr,ESP,dest,ip,AndroidStudio,TAG,IP地址,new
From: https://www.cnblogs.com/lesterbor/p/18046382

相关文章

  • linux查看ssh当前访问的ip地址
    netstat-anp|grep:22|grepESTABLISHED|awk'{print$5}'|cut-d:-f1|sort|uniq-c|sort-n参数解释:1.`netstat-anp`:列出所有的网络连接2.`grep:22`:筛选出SSH端口连接3.`grepESTABLISHED`:筛选出已经建立的连接4.`awk'{print$5}'`:提取出连接的IP地......
  • 脚本检查IP地址和MAC是否对应
    需求需要把一批次的IP地址和MAC地址进行绑定,如果该IP地址没有和MAC对应则输出脚本如下#catcheck_arp.sh#!/bin/bash#检查ip地址和mac是否对应IpList=()MacList=("<incomplete>""<incomplete>""<incomplete>""74:56:3c:63:c4:c7""<incom......
  • Java获取客户端IP地址进行记录
    1、编写工具类IpUtilspublicclassIpUtils{/***访问IP:0:0:0:0:0:0:0:1*访问IP:192.168.1.10*/privatestaticfinalStringIP_UTILS_FLAG=",";privatestaticfinalStringUNKNOWN="unknown";privatestati......
  • (27/60)复原IP地址、子集、子集Ⅱ
    阶段性还完了旧账复原IP地址leetcode:93.复原IP地址回溯法思路和分割回文串类似,只是回文串检测改为IP合法检测。终止条件也值得注意:复杂度分析时间复杂度:空间复杂度:注意点代码实现递归不一定要返回!!classSolution{private:vector<string>result;vec......
  • 代码随想录算法训练营第二十七天| 93.复原IP地址 78.子集 90.子集II
    复原IP地址 题目链接:93.复原IP地址-力扣(LeetCode)思路:投降。在判断字符串是否合法这部分遇到了困难。classSolution{private:vector<string>result;//记录结果//startIndex:搜索的起始位置,pointNum:添加逗点的数量voidbacktracking(string&s,int......
  • 代码随想录算法训练营第二十七天 | 90.子集II , 78.子集, 93.复原IP地址
    93.复原IP地址 已解答中等 相关标签相关企业 有效IP地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。例如:"0.1.2.201" 和"192.168.1.1" 是 有效 IP地址,但是 "0.011.255.245"、"1......
  • 在K8S中,如何具体实现Pod的IP地址发生变化时,不影响正常服务使用?
    在Kubernetes中,Pod的IP地址变化通常是由调度器重新调度Pod、节点故障、Pod升级或缩放等原因引起的。为了确保PodIP变化时服务不受影响,你可以采取以下具体步骤:使用Service:创建一个Service,指定其Selector以匹配你的Pod标签。当Pod的IP地址发生变化时,Kubernetes会自动更新Serv......
  • Rocky9和CentOSStream9怎么设置固定IP地址
    Rocky9和CentOSStream9设置固定IP地址和CentOS不一样设置设置以下文件#cat/etc/NetworkManager/system-connections/ens3.nmconnection[connection]id=ens3uuid=322d81cf-5218-304d-b537-ddbb2a0eed07type=ethernetautoconnect-priority=-999interface-name=ens3times......
  • C#中判断Ip地址能否ping通
    有的时候,哪怕ip地址的格式是正确的,但是也有可能是一个不可到达的ip地址或者不在同一个子网,这种时候如果不做处理,很有可能会导致程序的连接出现问题从而崩溃。请尝试下面的代码:1staticboolPingIPAddress(stringipAddress,stringtargetIpAddress)2{3try4......
  • ## AndroidStudio安装和环境配置
    利用网盘资源,下载所需的sdk和AndroidStudio链接:https://pan.baidu.com/s/1d-7jRWhHwBU8DaustdJvVA提取码:8xec第一步:新建一个androidstudio,在这个文件夹下新建sdk,studio,work,第二步,运行安装包,在资料里面。点击next默认全选,点击next点击IAgree下一步直到安装到你新......