I'm trying to do something similar in creating a firewall/filtering application for Android. I'm in the middle of this, so take what I say with the appropriate sized grain of salt. :-)
The trouble with your/my situation is that you're taking packets off the virtual network interface given to you by VpnService, but then you're taking those packets and writing them out with a socket. A socket is intended to handle the transfer of application payload between client and server, not packets.
The socket will take any data you hand it, and wrap that data within a packet of its own creation (TCP if using Socket, UDP if using DatagramSocket as you are). In your case, the data you are handing the socket is itself a packet, and thus you end up with a packet within a packet (likely a TCP packet inside a UDP packet).
When the wrapped packet arrives at the server for your socket, the network interface and ServerSocket on that end will unwrap the payload and find that it is another packet. Probably not going to work because whatever is reading from the server-side socket (e.g. web server) is expecting application payload (e.g. HTTP headers/etc.).
Now, when you have a real VPN tunnel, the server-side of that tunnel is probably pulling your 'wrapped packet' payload out of the UDP packet it receives and is then handing that packet directly to a network interface that can interpret the packet itself.
Without this real VPN tunnel, your VpnService impl essentially has to become a virtual network interface itself, handling the TCP/UDP/etc. protocol between the virtual network interface and your code. Basically, packets read from your VPN interface have to be treated as an application data stream (packets collated and reassembled) before writing to your outgoing socket. Then, you have to somehow acknowledge the packets you just consumed from the interface. Then, you have to take incoming data from your Socket (which is a payload data stream), and break it up into packets that you can then send back to the output stream of your VPN interface. Finally, you need to handle acknowledgement traffic your virtual VPN interface will send in response to the packets you send it. This is not trivial to do.
I really hope I'm wrong about all this, and someone has a simple 'virtual network interface' written in Java that could be used to take the place of the real VPN tunnel. I haven't been able to find it.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…