【问题标题】:How to parse a proxy socks packet in java?如何在java中解析代理socks数据包?
【发布时间】:2014-11-23 09:49:06
【问题描述】:

我正在尝试构建一个基本的代理 4 服务器,我必须解析一个数据包并提取它的信息,如下所示:

1 byte (version)
1 byte (command)
2 byte (port)
4 byte (ip)
X byte (userID, builds a string by looping until '\0' is found)

到目前为止,这是我的代码:

InputStream reader = socket.getInputStream();

byte[] ver  = new byte[1];
byte[] cmd  = new byte[1];
byte[] port = new byte[2];
byte[] ip   = new byte[4];

reader.read(ver, 0, 1);  //should be: 4
reader.read(cmd, 1, 1);  //should be: 1
reader.read(port, 2, 2); //should be: 00, 80
reader.read(ip, 4, 4);   //should be: 217, 70, 182, 162

这是我从代码中得到的回复:[4, 1, 0, 80, -39, 70, -74, -94]

由于某种原因,我得到的 IP 部分总是错误的,我真的不知道为什么。我的第二个问题是:如果找不到 \0 字节,是否有一种简单而干净的方法来获取最后一个 userID 字符串部分,而不必构建一个可能最终永远挂起的混乱循环?

【问题讨论】:

  • 你能转储Stream数据byte-by-byte看看它包含什么吗?
  • @BoristheSpider: [4, 1, 0, 80, -39, 70, -74, -94, 0, 0](无用户 ID)

标签: java sockets networking network-programming


【解决方案1】:

扔掉它,使用DataInputStream的方法。它们会为您提供 int、short、long 和完全读取的字节数组,并为您处理网络字节排序。

【讨论】:

  • 谢谢。我会给DataInputStream 一个尝试和一些研究,然后回复你。
  • 我同意这是大势所趋,并且在当今使用!但是,请不要只介绍术语,总是留下一些例子。您自己可能会因此收到反对票!
  • @shekharsuman 不要把话放在我嘴里。我没有说任何关于“总体趋势”的内容,而且这个解决方案自 1996 年以来就已在 Java 中使用,而不仅仅是“现在”。我希望任何称职的计算机程序员都能够根据这些信息设计出正确的解决方案。
  • 这解决了我的问题,这正是我想要的。谢谢!至于负IP值,我必须按照shekhar的建议将它们转换为int,但使用DataInputStream.readUnsignedByte
  • @shekharsuman 我不是在猜测这个。我在 1997 年使用它。检查你的事实。 DataInputStream标记为@since 1.0,即1996年。这里不要发表个人言论。
【解决方案2】:

您收到的第一个问题都是由于字节溢出,因此在 Java 中字节范围从 -128 到 127 变为负数。

查看this question,我在这个论坛上询问过 byte[] 的魔力(问题)...

说真的,如果这是你对最后一个字段的方法,(ip)---我相信你不会使用对字节的直接改革得到正确的答案。可能的解决方案似乎使用其他方法,例如存储在临时 int[] 中,例如

int[] ip   = new int[4];
byte[] temp = new byte[4];
reader.read(temp, 4, 4);   //should be: 217, 70, 182, 162
for(int i=0;i<temp.length;i++)
{
 if(temp[i]<0)
 ip[i]=(int)(256+temp[i]);  // careful here
 else
 ip[i]=(int)temp[i];
}

而且,对于第二个问题,我认为更好的解决方案是使用 String.length() 获取字符串部分的长度。

 int len = userID.length();  // assume user-id would be String type
 userid = new byte[len];   // notice the difference between userid and userID
 reader.read(userid,0,len);
 // I am confused as to how are you reading input from user,
 // if you clarify further,I'll update my answer...

【讨论】:

  • 谢谢,我会试试int[] 并回复您。至于我的问题的第二部分,用户 ID 字符串是代理客户端为自己设置的。除了等待\0 字节之外,我无法知道它们的大小。
  • 在忽略read()方法返回的值的情况下编写正确的网络代码是完全不可能的。
  • @shekhar suman:请问您是否需要更多说明。抱歉,不是我对你投了反对票。
  • @shekarsuman 如果关于“变通办法”的评论是针对我的,那是无稽之谈。
  • 对不起@EJP,如果这伤害了你。但是,为什么你玩得这么粗鲁。感谢您在回答下方的提示。
猜你喜欢
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 1970-01-01
  • 2014-03-20
相关资源
最近更新 更多