Two different questions
Blocking and non blocking describe what happens when an operation cannot complete right now. Synchronous and asynchronous describe who does the work of moving the data and when you find out it finished. The two ideas are related but not the same.
Synchronous IO
In synchronous IO the call you make is the call that performs the transfer. Even a non blocking read is synchronous, because when you finally call read the kernel copies the bytes during your call and hands them back before returning. You are present for the copy.
Asynchronous IO
In asynchronous IO you submit a request and the kernel performs the entire transfer in the background. You hand over a buffer, the kernel fills it, and later it signals completion through a callback, a completion queue, or a signal. You were not present for the copy and you did not retry.
Putting them together
- Synchronous plus blocking is the classic one thread per client model
- Synchronous plus non blocking is the readiness model used by event loops
- Asynchronous is the completion model where the kernel finishes the work for you
Key idea
Synchronous IO means you perform and witness the transfer, while asynchronous IO means the kernel completes it and notifies you afterward.