IO plugins are the ones used to wrap the open, read, write and 'system' on virtual file systems.
The cool thing of IO plugins is that you can make radare understand that any thing can be handled as a plain file. A socket connection, a remote radare session, a file, a process, a device, a gdb session, etc..
So, when radare reads a block of bytes, is the task of the IO plugin to get these bytes from any place and put them in the internal buffer.
IO plugins are selected while opening a file by its URI. Here'r some examples:
# Debugging URIs
$ radare dbg:///bin/ls
$ radare pid://1927
# Remote sessions
$ radare listen://:9999
$ radare connect://localhost:9999
# Virtual buffers
$ radare malloc://1024
You can get a list of the radare IO plugins by typing 'radare -L':
$ radare -L
haret Read WCE memory ( haret://host:port )
debug Debugs or attach to a process ( dbg://file or pid://PID )
gdb Debugs/attach with gdb (gdb://file, gdb://PID, gdb://host:port)
gdbx GDB shell interface 'gdbx://program.exe args' )
shm shared memory ( shm://key )
mmap memory mapped device ( mmap://file )
malloc memory allocation ( malloc://size )
remote TCP IO ( listen://:port or connect://host:port )
winedbg Wine Debugger interface ( winedbg://program.exe )
socket socket stream access ( socket://host:port )
gxemul GxEmul Debugger interface ( gxemul://program.arm )
posix plain posix file access