socat 接受连接但忽略发送的字节

socat 接受连接但忽略发送的字节

我正在尝试使用 通过 TCP 连接到串行适配器socat

这甚至涵盖了官方文档并且(理论上)应该可以工作。

我首先启动服务器

$ socat -d -d -d -x -v tcp-l:9000,reuseaddr,fork file:/dev/tty.usbserial-00000000,nonblock,raw,echo=0
socat[96183] I socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat[96183] I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (rg/)
socat[96183] I This product includes software written by Tim Hudson ([email protected])
socat[96183] I setting option "so-reuseaddr" to 1
socat[96183] I setting option "fork" to 1
socat[96183] I socket(2, 1, 6) -> 5
socat[96183] I starting accept loop
socat[96183] N listening on LEN=16 AF=2 0.0.0.0:9000

然后我向套接字发送一些数据,但nc没有退出。

echo "Hello world" | nc localhost 9000

尽管我看到连接被接受,但没有数据传输socat

socat[96183] I accept(5, {2, LEN=16 AF=2 127.0.0.1:62079}, 16) -> 6
socat[96183] N accepting connection from LEN=16 AF=2 127.0.0.1:62079 on LEN=16 AF=2 127.0.0.1:9000
socat[96183] I permitting connection from LEN=16 AF=2 127.0.0.1:62079
socat[96183] N forked off child process 96196
socat[96183] I close(6)
socat[96183] I still listening
socat[96183] N listening on LEN=16 AF=2 0.0.0.0:9000
socat[96196] I just born: child process 96196
socat[96196] I close(4)
socat[96196] I close(3)
socat[96196] I just born: child process 96196
socat[96196] I close(5)
socat[96196] I setting option "o-nonblock" to 1
socat[96196] I setting option "raw"
socat[96196] I setting option "echo" to 0
socat[96196] N opening character device "/dev/tty.usbserial-00000000" for reading and writing
socat[96196] I open("/dev/tty.usbserial-00000000", 06, 0666) -> 5
socat[96196] I resolved and opened all sock addresses
socat[96196] N starting data transfer loop with FDs [6,6] and [5,5]

服务器至少应该打印:

> 2023/04/24 17:15:14.000904245  length=12 from=0 to=11
 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a              Hello world.
--
Hello world

但它却保持沉默。

进一步提高调试级别,当连接被接受时会发生这种情况:

socat[96487] D select -> (, 0x20, 0x0, 0x0, NULL/0.000000), 1
socat[96487] D accept(5, 0x16eeaac00, 0x16eeaa710)
socat[96487] I accept(5, {2, LEN=16 AF=2 127.0.0.1:62354}, 16) -> 6
socat[96487] D fcntl(6, 2, 1)
socat[96487] D fcntl() -> 0
socat[96487] D getpeername(6, 0x16eeaa990, 0x16eeaa6f4{108})
socat[96487] D getpeername(, {LEN=16 AF=2 127.0.0.1:62354}, {16}) -> 0
socat[96487] D getsockname(6, 0x16eeaa920, 0x16eeaa6f0{108})
socat[96487] D getsockname(, {LEN=16 AF=2 127.0.0.1:9000}, {16}) -> 0
socat[96487] N accepting connection from LEN=16 AF=2 127.0.0.1:62354 on LEN=16 AF=2 127.0.0.1:9000
socat[96487] I permitting connection from LEN=16 AF=2 127.0.0.1:62354
socat[96487] D sigprocmask(1, 0x100080000, 0x0)
socat[96487] D sigprocmask() -> 0
socat[96487] D fork()
socat[96487] D fork() -> 96493
socat[96487] N forked off child process 96493
socat[96487] I close(6)
socat[96487] D close()  -> 0
socat[96487] D sigprocmask(2, 0x100080000, 0x0)
socat[96487] D sigprocmask() -> 0
socat[96487] I still listening
socat[96487] N listening on LEN=16 AF=2 0.0.0.0:9000
socat[96487] D select(6, &0x28, &0x0, &0x0, NULL/0.000000)
socat[96493] D fork() -> 0
socat[96493] D getpid()
socat[96493] D getpid() -> 96493
socat[96493] I just born: child process 96493
socat[96493] D setenv("SOCAT_PID", "0", 1)
socat[96493] D setenv() -> 0
socat[96493] I close(4)
socat[96493] D close()  -> 0
socat[96493] I close(3)
socat[96493] D close()  -> 0
socat[96493] D getpid()
socat[96493] D getpid() -> 96493
socat[96493] D sigprocmask(2, 0x100080000, 0x0)
socat[96493] D sigprocmask() -> 0
socat[96493] I just born: child process 96493
socat[96493] D setenv("SOCAT_PID", "96493", 1)
socat[96493] D setenv() -> 0
socat[96493] I close(5)
socat[96493] D close()  -> 0
socat[96493] D setenv("SOCAT_SOCKADDR", "127.0.0.1", 1)
socat[96493] D setenv() -> 0
socat[96493] D setenv("SOCAT_SOCKPORT", "9000", 1)
socat[96493] D setenv() -> 0
socat[96493] D setenv("SOCAT_PEERADDR", "127.0.0.1", 1)
socat[96493] D setenv() -> 0
socat[96493] D setenv("SOCAT_PEERPORT", "62354", 1)
socat[96493] D setenv() -> 0
socat[96493] D xioopen("file:/dev/tty.usbserial-00000000,nonblock,raw,echo=0")
socat[96493] D calloc(1, 848)
socat[96493] D calloc() -> 0x13b005500
socat[96493] D malloc(1024)
socat[96493] D malloc() -> 0x13a808600
socat[96493] I setting option "o-nonblock" to 1
socat[96493] I setting option "raw"
socat[96493] I setting option "echo" to 0
socat[96493] D stat(/dev/tty.usbserial-00000000, 0x16eeaace0)
socat[96493] D stat(, {-1775528684,2849,020666,1,0,0,150994948,0,65536,0,...}) -> 0
socat[96493] N opening character device "/dev/tty.usbserial-00000000" for reading and writing
socat[96493] D open("/dev/tty.usbserial-00000000", 06, 0666)
socat[96493] I open("/dev/tty.usbserial-00000000", 06, 0666) -> 5
socat[96493] D isatty(5)
socat[96493] D isatty() -> 1
socat[96493] D tcgetattr(5, 0x13b005658)
socat[96493] D tcgetattr(, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff}) -> 0
socat[96493] D tcgetattr(5, 0x100f94980)
socat[96493] D tcgetattr(, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff}) -> 0
socat[96493] D tcsetattr(5, 1, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff})
socat[96493] D tcsetattr() -> 0
socat[96493] D fcntl(5, 2, 1)
socat[96493] D fcntl() -> 0
socat[96493] I resolved and opened all sock addresses
socat[96493] D posix_memalign(0x16eeaae68, 16384, 16385)
socat[96493] D posix_memalign(...) -> 0
socat[96493] N starting data transfer loop with FDs [6,6] and [5,5]
socat[96493] D data loop: sock1->eof=0, sock2->eof=0, closing=0, wasaction=1, total_to={0.000000}
socat[96493] D select(7, &0x60, &0x60, &0x0, NULL/0.000000)
socat[96493] D select -> (, 0x40, 0x40, 0x0, NULL/0.000000), 2
socat[96493] D data loop: sock1->eof=0, sock2->eof=0, closing=0, wasaction=1, total_to={0.000000}
socat[96493] D select(6, &0x20, &0x20, &0x0, NULL/0.000000)

为了降低复杂性,我还尝试使用非分叉服务器:

socat[96591] D select -> (, 0x20, 0x0, 0x0, NULL/0.000000), 1
socat[96591] D accept(5, 0x16dbaac00, 0x16dbaa710)
socat[96591] I accept(5, {2, LEN=16 AF=2 127.0.0.1:62420}, 16) -> 6
socat[96591] D fcntl(6, 2, 1)
socat[96591] D fcntl() -> 0
socat[96591] D getpeername(6, 0x16dbaa990, 0x16dbaa6f4{108})
socat[96591] D getpeername(, {LEN=16 AF=2 127.0.0.1:62420}, {16}) -> 0
socat[96591] D getsockname(6, 0x16dbaa920, 0x16dbaa6f0{108})
socat[96591] D getsockname(, {LEN=16 AF=2 127.0.0.1:9000}, {16}) -> 0
socat[96591] N accepting connection from LEN=16 AF=2 127.0.0.1:62420 on LEN=16 AF=2 127.0.0.1:9000
socat[96591] I permitting connection from LEN=16 AF=2 127.0.0.1:62420
socat[96591] I close(5)
socat[96591] D close()  -> 0
socat[96591] D setenv("SOCAT_SOCKADDR", "127.0.0.1", 1)
socat[96591] D setenv() -> 0
socat[96591] D setenv("SOCAT_SOCKPORT", "9000", 1)
socat[96591] D setenv() -> 0
socat[96591] D setenv("SOCAT_PEERADDR", "127.0.0.1", 1)
socat[96591] D setenv() -> 0
socat[96591] D setenv("SOCAT_PEERPORT", "62420", 1)
socat[96591] D setenv() -> 0
socat[96591] D xioopen("file:/dev/tty.usbserial-00000000,nonblock,raw,echo=0")
socat[96591] D calloc(1, 848)
socat[96591] D calloc() -> 0x14f004200
socat[96591] D malloc(1024)
socat[96591] D malloc() -> 0x14f808200
socat[96591] I setting option "o-nonblock" to 1
socat[96591] I setting option "raw"
socat[96591] I setting option "echo" to 0
socat[96591] D stat(/dev/tty.usbserial-00000000, 0x16dbaace0)
socat[96591] D stat(, {-1775528684,2849,020666,1,0,0,150994948,0,65536,0,...}) -> 0
socat[96591] N opening character device "/dev/tty.usbserial-00000000" for reading and writing
socat[96591] D open("/dev/tty.usbserial-00000000", 06, 0666)
socat[96591] I open("/dev/tty.usbserial-00000000", 06, 0666) -> 5
socat[96591] D isatty(5)
socat[96591] D isatty() -> 1
socat[96591] D tcgetattr(5, 0x14f004358)
socat[96591] D tcgetattr(, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff}) -> 0
socat[96591] D tcgetattr(5, 0x102294980)
socat[96591] D tcgetattr(, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff}) -> 0
socat[96591] D tcsetattr(5, 1, {00000000,00000000,00004b00,00000000, 9600,9600, 04,ff,ff,7f,17,15,12,ff,03,1c,1a,19,11,13,16,0f,01,00,14,ff})
socat[96591] D tcsetattr() -> 0
socat[96591] D fcntl(5, 2, 1)
socat[96591] D fcntl() -> 0
socat[96591] I resolved and opened all sock addresses
socat[96591] D posix_memalign(0x16dbaae68, 16384, 16385)
socat[96591] D posix_memalign(...) -> 0
socat[96591] N starting data transfer loop with FDs [6,6] and [5,5]
socat[96591] D data loop: sock1->eof=0, sock2->eof=0, closing=0, wasaction=1, total_to={0.000000}
socat[96591] D select(7, &0x60, &0x60, &0x0, NULL/0.000000)
socat[96591] D select -> (, 0x40, 0x40, 0x0, NULL/0.000000), 2
socat[96591] D data loop: sock1->eof=0, sock2->eof=0, closing=0, wasaction=1, total_to={0.000000}
socat[96591] D select(6, &0x20, &0x20, &0x0, NULL/0.000000)

两者都没有按预期工作。我尝试了除 之外的其他客户端nc。USB 适配器工作正常,并充当连接了 tx 和 rx 的空调制解调器。

有什么提示我可能遗漏了什么吗?我正在 macOS 12.6 上尝试这个,但它也应该可以在 linux 上运行。

答案1

事实证明,/dev/tty.*vs/dev/cu.*在这里起了很大的作用。

日志文件似乎表明串行设备在使用时尚未准备好,/dev/tty.*而使用时它就是这样工作的/dev/cu.*

2023/04/24 19:06:35 socat[99178] I open("/dev/cu.usbserial-00000000", 06, 0666) -> 5
2023/04/24 19:06:35 socat[99178] I resolved and opened all sock addresses
2023/04/24 19:06:35 socat[99178] N starting data transfer loop with FDs [6,6] and [5,5]
> 2023/04/24 19:06:35.000460209  length=12 from=0 to=11
 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a              Hello world.
--
2023/04/24 19:06:35 socat[99178] I transferred 12 bytes from 6 to 5
2023/04/24 19:06:35 socat[99178] N socket 1 (fd 6) is at EOF
< 2023/04/24 19:06:35.000465202  length=3 from=0 to=2
 48 65 6c                                         Hel
--
2023/04/24 19:06:35 socat[99178] I transferred 3 bytes from 5 to 6
< 2023/04/24 19:06:35.000481226  length=9 from=3 to=11
 6c 6f 20 77 6f 72 6c 64 0a                       lo world.
--
2023/04/24 19:06:35 socat[99178] I transferred 9 bytes from 5 to 6

cu我仍然希望了解和之间的细节ttySO 帖子确实解释了一点- 但我不确定它是否已经确切地说明了为什么它在这里有所不同。特别是考虑到screen也适用于tty.*

但目前解决方案(在 macOS 上)是使用该cu设备。

相关内容