如何在java中解析代理socks数据包?

如何在java中解析代理socks数据包?,java,sockets,networking,network-programming,Java,Sockets,Networking,Network Programming,我正在尝试构建一个基本的proxy 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 byt

我正在尝试构建一个基本的proxy 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字符串部分,而不必构建一个可能永远挂起的混乱循环


谢谢。

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

查看我在论坛上要求了解的关于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];
}

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

您可以转储
数据
字节
-by-
字节
以查看它包含的内容吗?@boristesspider:[4,1,0,80,-39,70,-74,-94,0,0](无用户ID)谢谢,我将提供
int[]
a请稍后再试。至于我问题的第二部分,userID字符串是代理客户端为自己设置的。除非等待
\0
字节,否则我无法判断它们的大小。完全不可能在忽略
read()
方法返回的值的情况下编写正确的网络代码。@shekhar suman:请询问是否需要更多说明。很抱歉,不是我否决了你。@shekarsuman如果关于“变通办法”的评论是针对我的,那就是胡说八道。抱歉@EJP,如果这伤害了你。但是,你为什么玩得这么粗鲁。谢谢你在回答下面的提示。我会尝试一下DataInputStream并做一些研究,然后再给你回复。我同意这是大势所趋,并且在当今使用!但是,请不要只介绍术语,总是留下一些例子。你自己可能会因此而获得反对票@别把话塞进我嘴里。我没有说什么“一般趋势”,这个解决方案从1996年开始在Java中使用,而不仅仅是“现在”。我希望任何有能力的计算机程序员都能根据这些信息设计出正确的解决方案。这解决了我的问题,这正是我想要的。非常感谢。至于负的IP值,我必须按照shekhar的建议将它们转换为int,但使用的是
DataInputStream.readUnsignedByte
@shekharsuman,我不是在猜测这一点。我在1997年使用过它。检查你的事实
DataInputStream
从1996年的1.0版开始标记为
。不要在这里发表个人评论。
 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...