其实网络协议比较简单,一般都是一个固定的套路: 传 输 包 = 传 输 的 数 据 + 数 据 信 息 + 数 据 校 验 传输包=传输的数据+数据信息+数据校验 传输包=传输的数据+数据信息+数据校验socat工具是感觉是一个tcp/ip协议的转换,网上将socat比作协议的水管接头。个人感觉还是比较形象的。
既然是工具,那就要知道工具的使用方法:
$ ./socat -h # 我在帮助信息中加入一些中文,方便大家理解
socat by Gerhard Rieger - see www.dest-unreach.org
Usage:
socat [options] <bi-address> <bi-address>
options:
-V print version and feature information to stdout, and exit
-h|-? print a help text describing command line options and addresses
-hh like -h, plus a list of all common address option names
-hhh like -hh, plus a list of all available address option names
-d increase verbosity (use up to 4 times; 2 are recommended)
-D analyze file descriptors before loop
-ly[facility] log to syslog, using facility (default is daemon)
# -lf 指定日志文件路径
-lf<logfile> log to file
-ls log to stderr (default if no other log)
-lm[facility] mixed log mode (stderr during initialization, then syslog)
-lp<progname> set the program name used for logging
-lu use microseconds for logging timestamps
-lh add hostname to log messages
-v verbose data traffic, text
-x verbose data traffic, hexadecimal
-b<size_t> set data buffer size (8192)
-s sloppy (continue on error)
-t<timeout> wait seconds before closing second channel
-T<timeout> total inactivity timeout in seconds
-u unidirectional mode (left to right)
-U unidirectional mode (right to left)
-g do not check option groups
-L <lockfile> try to obtain lock, or fail
-W <lockfile> try to obtain lock, or wait
-4 prefer IPv4 if version is not explicitly specified
-6 prefer IPv6 if version is not explicitly specified
bi-address:
pipe[,<opts>] groups=FD,FIFO
<single-address>%<single-address>
<single-address>
single-address:
<address-head>[,<opts>]
address-head: #这个头部,好像大小写不敏感
abstract-client:<filename> rwb groups=FD,SOCKET,RETRY,UNIX
abstract-connect:<filename> rwb groups=FD,SOCKET,RETRY,UNIX
abstract-listen:<filename> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,UNIX
abstract-recv:<filename> r groups=FD,SOCKET,RETRY,UNIX
abstract-recvfrom:<filename> r b groups=FD,SOCKET,CHILD,RETRY,UNIX
abstract-sendto:<filename> wb groups=FD,SOCKET,RETRY,UNIX
create:<filename> rwb groups=FD,REG,NAMED
exec:<command-line> rwb groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
exec:<command-line> r w groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
exec:<command-line> w r groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
exec:<command-line> b b groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
exec1:<command-line> w r groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
fd:<num> rwb groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
fd:<numout>:<numin> b groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
gopen:<filename> rwb groups=FD,FIFO,BLK,REG,SOCKET,NAMED,OPEN,TERMIOS,UNIX
interface:<interface> rwb groups=FD,SOCKET
ip-datagram:<host>:<protocol> rwb groups=FD,SOCKET,RANGE,IP4,IP6
ip-recv:<protocol> r groups=FD,SOCKET,RANGE,IP4,IP6
ip-recvfrom:<protocol> r b groups=FD,SOCKET,CHILD,RANGE,IP4,IP6
ip-sendto:<host>:<protocol> wb groups=FD,SOCKET,IP4,IP6
ip4-datagram:<host>:<protocol> rwb groups=FD,SOCKET,RANGE,IP4
ip4-recv:<protocol> r groups=FD,SOCKET,RANGE,IP4
ip4-recvfrom:<protocol> r b groups=FD,SOCKET,CHILD,RANGE,IP4
ip4-sendto:<host>:<protocol> wb groups=FD,SOCKET,IP4
ip6-datagram:<host>:<protocol> rwb groups=FD,SOCKET,RANGE,IP6
ip6-recv:<protocol> r groups=FD,SOCKET,RANGE,IP6
ip6-recvfrom:<protocol> r b groups=FD,SOCKET,CHILD,RANGE,IP6
ip6-sendto:<host>:<protocol> wb groups=FD,SOCKET,IP6
nop r w groups=
nop w r groups=
nop b b groups=
open:<filename> rwb groups=FD,FIFO,BLK,REG,NAMED,OPEN,TERMIOS
openssl-client rwb b groups=CHILD,RETRY,OPENSSL
openssl-client:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,OPENSSL
openssl-server rwb b groups=CHILD,RETRY,OPENSSL
openssl-server:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP,OPENSSL
pipe b groups=FD,FIFO,NAMED,OPEN
pipe:<filename> rwb groups=FD,FIFO,NAMED,OPEN
proxy:<host>:<port> rwb b groups=CHILD,RETRY,HTTP
proxy:<proxy-server>:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,HTTP
pty rwb groups=FD,NAMED,TERMIOS,PTY
pty:<symlink> rwb groups=FD,NAMED,TERMIOS,PTY
readline r b groups=FD,READLINE,TERMIOS
sctp-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,SCTP
sctp-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,SCTP
sctp4-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,SCTP
sctp4-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,SCTP
sctp6-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP6,SCTP
sctp6-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,SCTP
socket-connect:<domain>:<protocol>:<remote-address>rwb groups=FD,SOCKET,CHILD,RETRY
socket-datagram:<domain>:<type>:<protocol>:<remote-address>rwb groups=FD,SOCKET,RANGE
socket-listen:<domain>:<protocol>:<local-address>rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE
socket-recv:<domain>:<type>:<protocol>:<local-address>r groups=FD,SOCKET,RANGE
socket-recvfrom:<domain>:<type>:<protocol>:<local-address>rwb groups=FD,SOCKET,CHILD,RANGE
socket-sendto:<domain>:<type>:<protocol>:<remote-address>rwb groups=FD,SOCKET
socks4:<host>:<port> rwb b groups=CHILD,RETRY,SOCKS4
socks4:<socks-server>:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
socks4a:<host>:<port> rwb b groups=CHILD,RETRY,SOCKS4
socks4a:<socks-server>:<host>:<port>rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
socks5:<host>:<port> rwb b groups=SOCKS5
stderr w groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdin r groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdio rwb groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdout w groups=FD,FIFO,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
system:<shell-command> rwb groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
system:<shell-command> b b groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
system:<shell-command> r w groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
system:<shell-command> w r groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
system1:<shell-command> w r groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
# tcp 相关
tcp-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP
tcp-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP
tcp4-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP4,TCP
tcp4-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,TCP
tcp6-connect:<host>:<port> rwb groups=FD,SOCKET,CHILD,RETRY,IP6,TCP
tcp6-listen:<port> rwb groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,TCP
test r w groups=
test w r groups=
test b b groups=
testrev w r groups=
testuni w r groups=
tun:<ip-addr>/<bits> rwb groups=FD,NAMED,OPEN,INTERFACE
# udp相关
udp-connect:<host>:<port> rwb groups=FD,SOCKET,IP4,IP6,UDP
udp-datagram:<host>:<port> rwb groups=FD,SOCKET,RANGE,IP4,IP6,UDP
udp-listen:<port> r b groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,UDP
udp-recv:<port> r groups=FD,SOCKET,RANGE,IP4,IP6,UDP
udp-recvfrom:<port> r b groups=FD,SOCKET,CHILD,RANGE,IP4,IP6,UDP
udp-sendto:<host>:<port> wb groups=FD,SOCKET,IP4,IP6,UDP
udp4-connect:<host>:<port> rwb groups=FD,SOCKET,IP4,UDP
udp4-datagram:<host>:<port> rwb groups=FD,SOCKET,IP4,UDP
udp4-listen:<port> r b groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,UDP
udp4-recv:<port> r groups=FD,SOCKET,RANGE,IP4,UDP
udp4-recvfrom:<host>:<port> r b groups=FD,SOCKET,CHILD,RANGE,IP4,UDP
udp4-sendto:<host>:<port> wb groups=FD,SOCKET,IP4,UDP
udp6-connect:<host>:<port> rwb groups=FD,SOCKET,IP6,UDP
udp6-datagram:<host>:<port> rwb groups=FD,SOCKET,IP6,UDP
udp6-listen:<port> r b groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP6,UDP
udp6-recv:<port> r groups=FD,SOCKET,RANGE,IP6,UDP
udp6-recvfrom:<port> r b groups=FD,SOCKET,CHILD,RANGE,IP6,UDP
udp6-sendto:<host>:<port> wb groups=FD,SOCKET,IP6,UDP
unix-client:<filename> rwb groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-connect:<filename> rwb groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-listen:<filename> rwb groups=FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
unix-recv:<filename> r groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-recvfrom:<filename> r b groups=FD,SOCKET,NAMED,CHILD,RETRY,UNIX
unix-sendto:<filename> wb groups=FD,SOCKET,NAMED,RETRY,UNIX
其实我也不知道怎么注释,感觉比较分类和命令字面指示比较明显,我知道的先做个笔记。
地址头,这类参数加到地址前,指定当前socat管道端口的启动方式 [接收/发送,使用协议]
*-connect: 直的是链接已经存在的服务端口
*-listen: 新启动一个端口,socat监听这个端口
*-recv: 接受指定端口的信息
使用技巧:
*-listen, 一般都加一个fork参数,这样可以同时接受多个客户端。有很多其他的模式是不支持fork的,这个提示信息可能各个版本不一样,类似如下错误。
socat[8400] E parseopts(): option "fork" not supported with this address type.
总结:
官方文档写得很详细,我大概浏览了一遍,很多功能,很强大,项目大概思路就是,将各种网络协议,文件,管道,标准I/O 作为管道的一端,和另外一端的协议进行链接。实现数据的转接的效果。
参考: