【问题标题】:Simple STUN client in javajava中的简单STUN客户端
【发布时间】:2014-12-14 12:43:23
【问题描述】:

我找到了几个 java STUN 实现

Java and Which Stun libraries i should use?

另见:STUN, TURN, ICE library for Java

但它是具有许多类的罐子。我希望以单一方法或至少一个小类的形式找到一些简单的东西。就像下面的python代码一样。

https://github.com/jtriley/pystun/blob/develop/stun/init.py

为什么Java中的STUN如此庞大的合理答案也是可以接受的。

【问题讨论】:

    标签: java stun


    【解决方案1】:

    为什么 Java 中的 STUN 如此庞大的合理答案也是可以接受的。

    这是一个合理的问题。 STUN 的 99% 只是一个简单的回显/响应协议,客户端通过它与公共互联网之间的 NAT 来自我发现 IP 和端口映射。构建了a STUN library in C++,我有了一些见解。

    让我们考虑一下 STUN 库需要什么:

    • 一个消息编写器,它使用属性字段模式生成 STUN 消息,不仅允许字段以任何顺序出现,它还允许添加自定义属性。

    • 可以读回此类消息并转换数据的消息解析器 结构合理的代码使用。它需要安全地执行此操作并避免未处理的异常。

    • 用于发送/接收此类消息的套接字网络代码。 STUN 服务器在技术上需要监听 2 个 IP 和 2 个端口,这使得服务器的网络代码更加复杂。

    • 如果我们只关心绑定请求和绑定响应,我们会 完毕。但 STUN RFC 也定义了一组 NAT 分类测试。因此,需要额外的状态机逻辑来完成任何此类库。

    • 如果 STUN 库要一直使用协议提供的安全选项,则需要一定数量的加密代码来对消息进行散列和签名

    因此,将所有这些组合到一个库中,任何人都可以将其用于 STUN 的所有不同目的,包括映射地址发现、NAT 分类和 ICE 协商,它开始快速发展。

    您可以轻松地滚动一些对绑定请求的字节进行硬编码的套接字代码,然后进行一些破解解析以解析响应。这可能会满足您自己的需求,但永远不会以这种方式编写完善的开源库。

    JSTUN 是一个好的开始。我与原作者分享了一些互操作和错误修复代码。他没有积极维护它,但它是 RFC 3489 的一个很好的实现。我什至破解了它一次以在 Android 上运行。

    在 JSTUN 中生成 STUN 绑定请求。

    MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
    sendMH.generateTransactionID();
    
    // add an empty ChangeRequest attribute. Not required by the standard, but JSTUN server requires it
    ChangeRequest changeRequest = new ChangeRequest();
    sendMH.addMessageAttribute(changeRequest);
    
    byte[] data = sendMH.getBytes();
    
    // not shown - sending the message
    

    然后将响应解析回来:

    byte [] receivedData = new byte[500];
    
    // not shown - socket code that receives the messages into receivedData
    receiveMH.parseAttributes(receivedData);
    MappedAddress ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);    
    

    然后将上面的内容与一些套接字代码结合起来。可以在 DiscoveryTest.java 源文件中找到将上述内容与套接字代码相结合的最佳示例。你真的只需要这个类的test1() 方法中的代码。

    【讨论】:

      【解决方案2】:
          MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
          // sendMH.generateTransactionID();
      
          // add an empty ChangeRequest attribute. Not required by the
          // standard,
          // but JSTUN server requires it
      
          ChangeRequest changeRequest = new ChangeRequest();
          sendMH.addMessageAttribute(changeRequest);
      
          byte[] data = sendMH.getBytes();
      
      
          s = new DatagramSocket();
          s.setReuseAddress(true);
      
          DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName("stun.l.google.com"), 19302);
          s.send(p);
      
          DatagramPacket rp;
      
          rp = new DatagramPacket(new byte[32], 32);
      
          s.receive(rp);
          MessageHeader receiveMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingResponse);
          // System.out.println(receiveMH.getTransactionID().toString() + "Size:"
          // + receiveMH.getTransactionID().length);
          receiveMH.parseAttributes(rp.getData());
          MappedAddress ma = (MappedAddress) receiveMH
                  .getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
          System.out.println(ma.getAddress()+" "+ma.getPort());
      

      【讨论】:

        【解决方案3】:
        import java.io.IOException;
        import java.net.DatagramPacket;
        import java.net.DatagramSocket;
        import java.net.InetAddress;
        import java.net.InetSocketAddress;
        import java.net.SocketException;
        import java.net.SocketTimeoutException;
        import java.net.UnknownHostException;
        
        import de.javawi.jstun.attribute.ChangeRequest;
        import de.javawi.jstun.attribute.ChangedAddress;
        import de.javawi.jstun.attribute.ErrorCode;
        import de.javawi.jstun.attribute.MappedAddress;
        import de.javawi.jstun.attribute.MessageAttribute;
        import de.javawi.jstun.attribute.MessageAttributeException;
        import de.javawi.jstun.attribute.MessageAttributeParsingException;
        import de.javawi.jstun.header.MessageHeader;
        import de.javawi.jstun.header.MessageHeaderParsingException;
        import de.javawi.jstun.util.UtilityException;
        
        
        public class StunTest { public static void main(String[] args) throws UtilityException, IOException {
        
        
                MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
                // sendMH.generateTransactionID();
        
                // add an empty ChangeRequest attribute. Not required by the
                // standard,
                // but JSTUN server requires it
        
                ChangeRequest changeRequest = new ChangeRequest();
                sendMH.addMessageAttribute(changeRequest);
        
                byte[] data = sendMH.getBytes();
        
        
                DatagramSocket s = new DatagramSocket();
                s.setReuseAddress(true);
        
                DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName("stun.l.google.com"), 19302);
                s.send(p);
        
                DatagramPacket rp;
        
                rp = new DatagramPacket(new byte[32], 32);
        
                s.receive(rp);
                MessageHeader receiveMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingResponse);
                // System.out.println(receiveMH.getTransactionID().toString() + "Size:"
                // + receiveMH.getTransactionID().length);
                try {
                        receiveMH.parseAttributes(rp.getData());
                } catch (MessageAttributeParsingException e) {
                        e.printStackTrace();
                }
                MappedAddress ma = (MappedAddress) receiveMH
                        .getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
                System.out.println(ma.getAddress()+" "+ma.getPort());
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-16
          • 1970-01-01
          • 1970-01-01
          • 2015-08-16
          • 1970-01-01
          相关资源
          最近更新 更多