我正在尝试使用VpnService.I修改ToyVpn为Android构建一个TCP / IP嗅探器示例我正确地从描述符获取输出IP数据包,目前我只是尝试将其发送到没有IP的目标套接字和TCP标头并在日志中显示来自目标服务器的响应。实际上,我要做的就是在网络中传送数据包,当我有响应时,将它写在OutputStream中,与ParcelFileDescriptor相对应。
我正在使用此代码:
while (vpnInterface != null && vpnInterface.getFileDescriptor() != null
&& vpnInterface.getFileDescriptor().valid()) {
packet.clear();
// Read the outgoing packet from the input stream.
final byte[] data = packet.array();
int length = in.read(data);
//use this to get the unsigned byte
int[] d = new int[data.length];
if (length > 0) {
packet.limit(length);
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < data.length; i++) {
d[i] = data[i] & 0xFF;
sb.append(d[i] + " ");
}
Log.i("packet", sb.toString());
Socket socket = SocketChannel.open().socket();
if ((null != socket) && (null != this)) {
this.protect(socket);
}
//connect to dest ip and port
socket.connect(new InetSocketAddress(d[16] + "." + d[17] + "."
+ d[18] + "." + d[19], (d[22] * 256) + d[23]));
DataOutputStream dOut = new DataOutputStream(
socket.getOutputStream());
DataInputStream dIn = new DataInputStream(
socket.getInputStream());
dOut.write(data, 40, data.length - 40);
dOut.flush();
dOut.close();
length = dIn.read(data);
if (length > 0) {
sb = new StringBuilder("");
for (int i = 0; i < data.length; i++) {
d[i] = data[i] & 0xFF;
sb.append(d[i] + " ");
}
Log.i("response", sb.toString());
dIn.close();
}
}
Thread.sleep(10);
}
问题是我在尝试从套接字读取InputStream时遇到ClosedChannelException。你有什么想法为什么会这样?我想知道如何管理来自dest套接字的输入数据包。
很抱歉,如果我犯了任何错误,但我是JAVA的初学者。
答案 0 :(得分:2)
您正在关闭InputStream
中的Socket
。 JavaDoc说:
关闭返回的InputStream将关闭相关的套接字。
通常,您永远不应该关闭您不拥有的流!
OutputStream
与socket.getOutputStream()
相同。如果你关闭它,套接字也将关闭!