I had a simple UDP ping server that used to work but no longer does since I upgraded to the latest tokio version. Originally I was using RecvDgram
but when that always returns an empty response (0 bytes). I then built my own version of a future to see if that would help, but it's the same result. I'm hoping you might have some tips or pointers on where I might be going wrong w/ my code or testing methodology.
Thanks!
Methodology
Here's my test methodology in case the problem is there.
Simulated client command: echo -e "hello world" | nc -u 127.0.0.1 3999
If I use nc for the server too, it receives "hello world"
I use the same client for my udp server w/ tokio, I always get a response like this, showing 0 bytes read:
poll_recv_from ready: (0, V4(127.0.0.1:52978))
received 0 bytes from 127.0.0.1:52978
tcpdump seems to show that the packets are going through. The top line is for the nc listener, the bottom line for my server.
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:41:41.800083 IP (tos 0x0, ttl 64, id 3279, offset 0, flags [DF], proto UDP (17), length 40)
127.0.0.1.55181 > 127.0.0.1.3999: [bad udp cksum 0xfe27 -> 0x88be!] UDP, length 12
11:41:52.368481 IP (tos 0x0, ttl 64, id 6240, offset 0, flags [DF], proto UDP (17), length 40)
127.0.0.1.54226 > 127.0.0.1.3999: [bad udp cksum 0xfe27 -> 0x8c79!] UDP, length 12
I just tried doing the same thing but sending the packet to my actual IP address instead of 127.0.0.1 and got the same problem, with 0 bytes returned.
Code
Here's the code for my future. I create the socket w/ UdpSocket::bind(&sock_addr)
.
struct UdpRecv
{
ctx: rsrc::IopCtx,
buffer: Vec<u8>,
}
impl Future for UdpRecv
{
type Item = rsrc::Event;
type Error = rsrc::Event;
fn poll(&mut self) -> Poll<rsrc::Event, rsrc::Event>
{
print!("UdpRecv::poll()\n");
let mut sock: UdpSocket = self.ctx.take_rsrc();
let result = match sock.poll_recv_from(&mut self.buffer) {
Ok(Async::Ready(ready_result)) => {
println!("poll_recv_from ready: {:?}", ready_result);
ready_result
}
Ok(Async::NotReady) => {
println!("poll_recv_from notready");
self.ctx.init_rsrc(Box::new(sock));
task::current().notify();
return Ok(Async::NotReady);
}
Err(e) => {
panic!("io error: {:?}", e);
}
};
let (nbytes, addr) = result;
println!("received {} bytes from {}", nbytes, addr);
let utf8 = String::from_utf8(self.buffer.clone()).unwrap();
let str_result = Val::Str(Lstr::from(utf8));
Ok(Async::Ready(rsrc::Event::Result(str_result, Some(Box::new(sock)))))
}
}