java中的简单STUN客户端
我发现了几个JavaStun实现 有java中的简单STUN客户端,java,stun,Java,Stun,我发现了几个JavaStun实现 有 JSTUN: 眩晕: 另见: 但它与许多类不一致。我希望找到一个简单的方法,或者至少是一个小类。就像下面的python代码一样 合理的答案为什么Java中的STUN如此巨大也是可以接受的。合理的答案为什么Java中的STUN如此巨大也是可以接受的 这是一个合理的问题。STUN的99%只是一个简单的echo/response协议,客户端可以通过NAT在它和公共互联网之间自行发现IP和端口映射。建造之后,我有了一些洞察力 让我们来考虑一下对STUN库的要
- JSTUN:
- 眩晕:
- 一个消息编写器,它使用属性字段模式生成STUN消息,该模式不仅允许字段以任何顺序显示,还允许添加自定义属性
- 一种消息解析器,可以读回这些消息并转换数据 结构合理,便于代码使用。它需要安全地执行此操作,并避免未处理的异常
- 用于发送/接收此类消息的套接字网络代码。从技术上讲,STUN服务器需要监听2个IP和2个端口,这使得服务器的网络代码更加复杂
- 如果我们只关心绑定请求和绑定响应,那么 完成。但是STUN RFC也定义了一组NAT分类测试。因此,需要额外的状态机逻辑来完成任何这样的库
- 如果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()
方法中的代码
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());
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());
}
}