我想使用Android的
现在我正在使用以下代码从服务器获取响应:
这段代码似乎要么极其缓慢,要么根本不起作用。有时候如果我去
VpnService
来捕获数据包,并基于IP地址进行过滤。我可以从“tun”接口正常获取数据包,但之后我不确定如何将它们转发到它们的原始目的地。根据这个答案中的评论,似乎我只需要:
- 创建一个新的套接字以连接到目标IP地址和端口
- 削减IP和TCP头以仅发送数据
- 在收到响应时重新附加IP和TCP头
- 将完整数据包发送到输出流
我尝试像这样发送数据:
Socket socket = new Socket();
socket.bind(new InetSocketAddress(0));
if (protect(socket)){
Log.e(TAG, "Socket protected");
}else{
Log.e(TAG, "Socket NOT protected");
}
socket.connect(new InetSocketAddress(ipPacket.getDestinationIp(), ipPacket.getDstPort()));
Log.e(TAG, "Socket connected: " + socket.isConnected());
socket.getOutputStream().write(getTCPHeader(getIpHeader(packet)[1])[1].array());
方法getTCPHeader(ByteArray packet)
和getIpHeader(ByteArray packet)
将数据包按照以下方式分成两个ByteArray
:
private ByteBuffer[] getIpHeader(ByteBuffer packet){
packet.position(0);
ByteBuffer ipHeader = ByteBuffer.allocate(20);
ByteBuffer data = ByteBuffer.allocate(packet.limit() - 20);
packet.get(ipHeader.array(), 0, 20);
packet.get(data.array(), 0, packet.limit() - 20);
return new ByteBuffer[]{ipHeader, data};
}
private ByteBuffer[] getTCPHeader(ByteBuffer packet){
packet.position(20);
ByteBuffer tcpHeader = ByteBuffer.allocate(20);
ByteBuffer data = ByteBuffer.allocate(packet.limit() - 20);
packet.get(tcpHeader.array(), 0, 20);
packet.get(data.array(), 0, packet.limit() - 40);
return new ByteBuffer[]{tcpHeader, data};
}
现在我正在使用以下代码从服务器获取响应:
ByteBuffer responsePacket = ByteBuffer.allocate(65535);
InputStream socketInputStream = socket.getInputStream();
try{
int responseLength = socketInputStream.read(responsePacket.array());
if (responseLength > 20){
Log.e(TAG, "===Server Response===");
Log.e(TAG, "Length: " + responseLength);
ByteBuffer trimmedResponseData = ByteBuffer.allocate(responseLength);
System.arraycopy(responseData.array(), 0, trimmedResponseData.array(), 0, responseLength);
String resp = "";
for (int i = 0; i < responseLength; i++){
resp += String.valueOf(responseData.get(i) + " ");
}
Log.e(TAG, "Response data: " + resp);
ByteBuffer finalPacket = ByteBuffer.allocate(40 + responseLength);
ByteBuffer swappedIpHeader = swapSrcDstAddress(getIpHeader(packet)[0]);
ByteBuffer swappedTcpHeader = swapTCPSrcDst(getTCPHeader(getIpHeader(packet)[1])[0]);
finalPacket.put(swappedIpHeader.array());
finalPacket.put(swappedTcpHeader.array());
finalPacket.put(serverResponseData.array());
Packet finPack = debugPacket(finalPacket);
Log.e("VPN", "Final packet --> Packet size: " + finPack.getTotalLength() + " from " + finPack.getSourceIp() + " src port: " + finPack.getSrcPort() + " going to " + finPack.getDestinationIp() + " dst port: " + finPack.getDstPort());
out.write(finalPacket.array());
}
}catch (Exception e){
//Log.e(TAG, "EXCEPTION: " + e);
e.printStackTrace();
}
这段代码似乎要么极其缓慢,要么根本不起作用。有时候如果我去
www.google.com
,它会加载得很慢,但大多数情况下它根本不会加载。有时我会在int responseLength = socketInputStream.read(serverResponse.array());
这一行上遇到以下错误:
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
是什么导致了这个错误,如何将这些数据包正确地转发到相应的目的地?非常感谢您的帮助!