What would be a good trait for sockets?

I'm designing traits for a socket. I'd like to use something from std library but I didn't find any. My idea is so I can create all sorts of sockets and then use like this: my_socket: Box<dyn Socket>.

I'm also very in doubt about using async or not, so I made 2 versions. Note that I also don't know if it's better to pass a callback to be called when data arrives or if it's ok for the client to poll (in the async case) or block when calling tcp_receive.

pub type OnTcpSocketData = Arc<dyn Fn(&[u8]) -> Result<usize, SocketReceiveError>>;
pub type OnUdpSocketData = Arc<dyn Fn(&[u8], IpAddr, u16) -> Result<usize, SocketReceiveError>>;

pub trait Socket {
    fn set_on_tcp_socket_data(on_tcp_socket_data: OnTcpSocketData);
    fn set_on_udp_socket_data(on_tcp_socket_data: OnUdpSocketData);
    fn tcp_socket_send(&mut self, data: &[u8]) -> Result<usize, SocketSendError>;
    fn udp_socket_send(&mut self, data: &[u8], addr: IpAddr) -> Result<usize, SocketSendError>;
    fn tcp_connect(&mut self, addr: IpAddr, port: u16) -> Result<(), SocketConnectionError>;
    fn tcp_receive(&mut self, f: &dyn Fn(&[u8])) -> Result<usize,SocketReceiveError>;
    fn udp_receive(&mut self, f: &dyn Fn(&[u8], IpAddr, u16)) -> Result<usize,SocketReceiveError>;
}

pub trait SocketAsync {
    fn set_on_tcp_socket_data(on_tcp_socket_data: OnTcpSocketData);
    fn set_on_udp_socket_data(on_tcp_socket_data: OnUdpSocketData);
    fn tcp_socket_send(&mut self, data: &[u8]) -> Pin<Box<dyn Future<Output=Result<usize, SocketSendError>>>>;
    fn udp_socket_send(&mut self, data: &[u8], addr: IpAddr) -> Pin<Box<dyn Future<Output=Result<usize, SocketSendError>>>>;
    fn tcp_connect(&mut self, addr: IpAddr, port: u16) -> Pin<Box<dyn Future<Output=Result<usize, SocketConnectionError>>>>;
    fn tcp_receive(&mut self, f: &dyn Fn(&[u8])) -> Pin<Box<dyn Future<Output=Result<usize,SocketReceiveError>>>>;
    fn udp_receive(&mut self, f: &dyn Fn(&[u8], IpAddr, u16)) -> Pin<Box<dyn Future<Output=Result<usize,SocketReceiveError>>>>;
}

I'm trying to take inspiration from Tokio's TcpStream which implements AsyncRead and AsyncWrite, which also has there utilities tokio::io::AsyncReadExt - Rust with simple functions like fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> which looks a lot like my tcP-receive

Am I in a good track?