【发布时间】:2014-04-23 23:43:55
【问题描述】:
我有一个程序使用 libssh2 来管理一些 Linux 机器。这相当简单:它连接到 Linux 机器,下载配置文件,然后保持 libssh2 连接打开(和空闲),以便如果用户按下 GUI 上的按钮,它可以根据需要向 Linux 机器发送适当的 shell 命令。
它使用非阻塞 I/O(通过 libssh2_session_set_blocking(session, 0)),因此网络 I/O 可以由单个线程处理,而会话 A 的活动不会被我的会话 B 阻塞读取或写入等。
这一切都很好。我说主要是因为只有当程序同时连接到许多(即几十个)盒子时才会出现一个奇怪的问题。发生的情况是会话都像往常一样连接,并且配置文件已成功下载,并且连接都像预期的那样处于空闲状态。但是在一些会话中,在下载完成后的几毫秒(即,在我已经 libssh2_channel_read()'d 所有配置文件字节之后,并且在 libssh2_channel_close() 成功之后),一些额外的数据字节(通常是 104 或140) 出现在会话的 TCP 套接字上,可供我读取并传递给 libssh2。
此时我有一个问题,因为(据我所知)libssh2 会话应该是空闲的,而且我不知道如何处理这些未经请求的数据字节。我的选择都不是真正令人满意的:
我可以忽略字节,但是 select() 会一直唤醒,因为字节在那里,这会导致线程旋转,只要程序打开,我的 CPU 使用率就会显着上升,所以这不好。
我可以停止 select()-ing 准备读取具有额外数据的套接字,但是我无法判断套接字是否被远程对等方关闭,我想成为能够在发生这种情况时通知用户。
我可以只 recv() 多余的字节并将它们扔掉,但这显然会破坏 libssh2 连接状态机的状态,因为下次我尝试使用它时(例如,当用户希望我使用它时)向机器发送 ssh 命令)该命令不会被发送。
我可以执行 sleep(1) 或关闭连接并重新连接,但对于我认为应该正确处理的问题,这些都是丑陋的变通方法。
所以我的问题是
这些奇怪的未经请求的字节是什么?
我应该调用什么函数来将它们传递给 libssh2 以使其快乐?
ps 以下是一些神秘接收字节的示例,通过使用带有 MSG_PEEK 标志的 recv() 获得:
--- peek'd data from session #1 (104 bytes): --------------------------------------------
0000: ..#|)62.!.A..... [ab 1f 23 7c 29 36 32 e8 21 cf 41 91 88 de 06 a4]
0016: xc.??n.+aJLS..di [78 63 f2 3f 3f 6e 16 2b 61 4a 4c 53 ab aa 64 69]
0032: ...d.]f.P...4;.3 [c2 d6 9e 64 b4 5d 66 db 50 ba 90 82 34 3b cc 33]
0048: cO"..5..Fr...Yy. [63 4f 22 ba b1 35 9c 00 46 72 a6 9c bb 59 79 a1]
0064: ..L....._..1.>.K [d2 fe 4c 2e e4 81 eb fd 5f 8e f2 31 da 3e c0 4b]
0080: ...........(d... [1d af df 0d 0f d1 ef 1e 07 d1 9f 28 64 f4 07 d3]
0096: 0...sl.. [30 b6 ee f7 73 6c cd 85]
--- peek'd data from session #2 (104 bytes): ----------------------------------------------
0000: g.5"....Q....... [67 d9 35 22 85 90 ab eb 51 95 11 0c e6 ca 9f de]
0016: ...)... .6V&.lkF [ed 04 cb 29 e9 87 95 20 85 36 56 26 a9 6c 6b 46]
0032: ...m).V....JS... [ce b2 d7 6d 29 bb 56 fc 8e 89 a2 4a 53 a9 02 19]
0048: .w1........kY... [a1 77 31 a1 fb f8 b7 94 ee e0 d3 6b 59 ea cc ae]
0064: ...~..[..vZ..... [e3 e8 f2 7e 2e 89 5b c4 82 76 5a da ff b6 ae 91]
0080: ......7.0Z..6g.J [8a cb c8 fc eb e1 37 8e 30 5a e5 b8 36 67 c7 4a]
0096: '...qJS. [27 da b8 8f 71 4a 53 ef]
--- peek'd data from session #3 (140 bytes): -------------------------------------------------
0000: ...u.d.E..>a.... [04 c3 b1 75 e5 64 d1 45 9e b0 3e 61 81 e9 9b b7]
0016: ..\.....n..D..e. [e4 a2 5c b5 9e da a9 b9 6e 96 b7 44 12 bd 65 d9]
0032: .|(Jp..,k.....r' [c0 7c 28 4a 70 15 90 2c 6b 01 02 1a e6 d1 72 27]
0048: ..%..R]E:...N.CU [0b 8c 25 eb cd 52 5d 45 3a c4 12 f2 4e 11 43 55]
0064: gix$...d:.m..Ps1 [67 69 78 24 a1 e9 85 64 3a d5 6d 91 1a 50 73 31]
0080: Z.]...8#...q..AW [5a ca 5d db 1d 1d 38 23 0e 05 99 71 98 d8 41 57]
0096: ..]....U.7...J.? [ee 86 5d d1 0c b8 ce 55 f6 37 b5 1c 0f 4a b2 3f]
0112: ...10.......h(.* [17 15 ee 31 30 ea ee e0 b9 07 d1 c9 68 28 83 2a]
0128: ....>..g9... [be c2 e4 f9 3e e2 ea 67 39 0f b2 8c]
【问题讨论】:
-
你能发布意外的字节吗?将它们编辑到您的问题中。
-
@EJP 完成(这里还有一些输入可以使此评论足够长)