socket通过UDP获得服务端IP并建立TCP连接

在不知道服务端IP的情况下能自动获取服务端IP并建立连接

1.服务端通过MulticastSocket发送本机IP到客户端

2.客户端接收到服务端的消息解析出服务端IP并建立基于TCP的socket连接;

说明:

DatagramSocket只允许数据报发送给指定的目标地址,而MulticastSocket可以将数据报以广播的方式发送到多个客户端

若要使用多点广播,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有所有主机都能收到该数据报。IP多点广播(或多点发送)实现了将单一信息发送到多个接受者的广播,其思想是设置一组特殊网络地址作为多点广播地址,每一个多点广播地址都被看做一个组,当客户端需要发送、接收广播信息时,加入到改组即可。

组播地址:称为组播组的一组主机所共享的地址。组播地址的范围在224.0.0.0--- 239.255.255.255之间(都为D类地址 1110开头)。 

 写的不对的地方欢迎大家批评指正

客户端代码:

   /*发送广播端的socket*/
    private MulticastSocket ms;
    String multicastHost = "224.0.0.130";
    InetAddress receiveAddress;
    private TextView showIPTxt;
    /*服务器IP*/
    private String serverIP;


 try {
            ms = new MulticastSocket(8888);
            receiveAddress = InetAddress.getByName(multicastHost);
            ms.joinGroup(receiveAddress);
            recevie();
        } catch (Exception e1) {
            e1.printStackTrace();
        }

   /**
     * @time: 2019/1/25 13:13
     * @description: 接收服务端UDP广播
     */private void recevie() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                byte buf[] = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf, buf.length);
                while (true) {
                    try {
                        ms.receive(dp);
                        serverIP = new String(buf, 0, dp.getLength());
                        Log.d(TAG, "run: clientIP===>" + serverIP);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                showIPTxt.setText(serverIP);
                            }
                        });
                        ms.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

服务端代码:

     private MulticastSocket ms;
    String multicastHost = "224.0.0.1";
    InetAddress receiveAddress;
    private TextView showIPTxt;
    private int num;

 try {
            ms = new MulticastSocket(8888);
            receiveAddress = InetAddress.getByName(multicastHost);
            ms.joinGroup(receiveAddress);
            sendUDP();
        } catch (Exception e1) {
            e1.printStackTrace();
        }


  /**
     * @time: 2019/1/25 10:15
     * @description: 发送UDP广播
     */
    private void sendUDP() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                DatagramPacket dataPacket = null;
                try {
                    ms.setTimeToLive(4);
                    //将本机的IP(这里可以写动态获取的IP)地址放到数据包里,其实server端接收到 
                   数据包后也能获取到发包方的IP的
                    byte[] data = getLocalIpAddress().getBytes();
                    //224.0.0.1为广播地址
                    InetAddress address = InetAddress.getByName("224.0.0.130");
                    ms.joinGroup(address);
                    dataPacket = new DatagramPacket(data, data.length);
                    dataPacket.setAddress(address);
                    dataPacket.setPort(8888);
                    while (true) {
                        num++;
                        ms.send(dataPacket);
                        Thread.sleep(1000);
                        Log.d(TAG, "run: ===>" + num);
                    }

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


  /**
     *  @time: 2019/1/25 10:23
     * @description: 获得本机IP
     */
    private String getLocalIpAddress() {
        try {
            Enumeration en = NetworkInterface.getNetworkInterfaces();
            for (; en.hasMoreElements(); ) {
                NetworkInterface intf = (NetworkInterface) en.nextElement();
                for (Enumeration enumIpAddr = intf.getInetAddresses(); 
                         enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = (InetAddress) enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && 
                           !inetAddress.isLinkLocalAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (SocketException ex) {

        }
        return null;
    }

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个比较广泛的问题,我会尽量给您介绍一下Socket编程的基本知识和一些示例代码。首先,Socket编程可以用于实现不同机器或者同一机器上的进程间通信,TCPUDP是两种经常使用的协议。下面我为您介绍一下TCPUDP的通信流程和一些基本的代码示例。 ## 基本概念 ### TCP TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。TCP在传输数据前需要先建立连接,而且必须保证传输的数据是可靠的,因此TCP通信相对来说比较安全可靠,但是由于需要建立连接和维护状态信息,因此TCP的效率相对较低。 ### UDP UDP(User Datagram Protocol,用户数据报协议)是一种面向无连接的传输协议,它不需要建立连接,只需要发送数据报即可。由于UDP不需要维护连接状态,因此效率比TCP高,但是由于它不保证数据传输的可靠性,因此在需要可靠性较高的场景下不太适合使用。 ### Socket Socket(套接字)是应用层与传输层之间的一个接口,它包含了IP地址和口号,可以用于实现进程间的通信。在Socket编程中,我们通常使用TCPUDP协议进行通信。 ## TCP通信示例 ### 服务 以下是一个使用TCP协议实现的服务示例代码,它接收客户发送的数据并将其打印出来: ```python import socket HOST = '' # 监听所有可用的接口 PORT = 8888 # 监听的口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print('Socket created') # 绑定socket对象到本地IP口号 try: s.bind((HOST, PORT)) except socket.error as msg: print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]) sys.exit() print('Socket bind complete') # 开始监听客户连接请求 s.listen(10) print('Socket now listening') # 等待客户连接 conn, addr = s.accept() print('Connected with ' + addr[0] + ':' + str(addr[1])) # 接收客户发送的数据并打印出来 while True: data = conn.recv(1024) if not data: break conn.sendall(data) print(data.decode('utf-8')) # 关闭socket对象 conn.close() s.close() ``` ### 客户 以下是一个使用TCP协议实现的客户示例代码,它向服务发送数据并接收服务返回的数据: ```python import socket HOST = '127.0.0.1' # 服务IP地址或主机名 PORT = 8888 # 服务口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print('Socket created') # 连接服务 s.connect((HOST, PORT)) print('Socket connected to ' + HOST + ' on port ' + str(PORT)) # 发送数据到服务 s.sendall(b'Hello, world') # 接收服务返回的数据并打印出来 data = s.recv(1024) print(data.decode('utf-8')) # 关闭socket对象 s.close() ``` ## UDP通信示例 ### 服务 以下是一个使用UDP协议实现的服务示例代码,它接收客户发送的数据并将其打印出来: ```python import socket HOST = '' # 监听所有可用的接口 PORT = 8888 # 监听的口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print('Socket created') # 绑定socket对象到本地IP口号 s.bind((HOST, PORT)) print('Socket bind complete') # 接收客户发送的数据并打印出来 while True: data, addr = s.recvfrom(1024) print(data.decode('utf-8')) # 关闭socket对象 s.close() ``` ### 客户 以下是一个使用UDP协议实现的客户示例代码,它向服务发送数据: ```python import socket HOST = '127.0.0.1' # 服务IP地址或主机名 PORT = 8888 # 服务口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print('Socket created') # 发送数据到服务 s.sendto(b'Hello, world', (HOST, PORT)) # 关闭socket对象 s.close() ``` 以上就是一个基本的Socket编程示例,如果您还有什么问题可以继续问我哦。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值