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

时间:2014-11-23 09:49:07

标签: java sockets networking network-programming

我正在尝试构建一个基本的代理服务器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部分总是错误的,我真的不知道为什么。我的第二个问题是:是否有一个简单而干净的方法来获取最后一个userID字符串部分,而不必构建一个凌乱的循环,如果找不到\0字节,它可能会永远挂起?

谢谢。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分: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()获取String-part的长度。

 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...