www.libssh2.org | Daily snapshots | Mailing list archive | Docs | Examples | github

Archive Index This month's Index

Subject: select() and example/direct_tcpip.c

select() and example/direct_tcpip.c

From: Kirk Wolf <kirk_at_dovetail.com>
Date: Tue, 14 Aug 2012 12:14:50 -0500

I'm new to working with libssh2, so I apologize in advance if I'm
asking about something that I should have been able to find in the
docs or examples.

(from the list archives 6 Oct 2011) -

Pavel Strashkin wrote:

> Steven Ayre wrote:

> > It seems the new idea is to do a select() or poll() on the socket,
> > then do a nonblocking read of both stdout and stderr. Can someone
> > clarify if that's correct please?

> This is the only way it works yes. See example/direct_tcpip.c for an
> example of how this can look. (This also considers another socket in
> the same select() call.)

In examples/direct_tcpip.c, and I see that the only fd in the select()
set is the socket to be forwarded, and not the ssh socket.

I would like to implement an efficient method to forward several
bi-directional sockets over direct-tcpip channels at once. The
example/direct_tcpip.c doesn't seem to handle bidirectional data
efficiently at all - it hangs a select() with only the forward socket
in the read set - what happens when data arrives in the other

Also, BTW, there is a minor bug in the example code:

+++ example/direct_tcpip.c
@@ -233,7 +233,7 @@
             wr = 0;
             do {
- i = libssh2_channel_write(channel, buf, len);
+ i = libssh2_channel_write(channel, buf + wr, len - wr);
                 if (i < 0) {
                     fprintf(stderr, "libssh2_channel_write: %d\n", i);
                     goto shutdown;

The documentation for the deprecated libssh2_poll(3) function says:
"We encourage users to instead use the poll(3) or select(3) functions
to check for socket activity or when specific sockets are ready to get
recevied from or send to."

This makes sense to me, but if I add the ssh socket to the read select
fd set, what then?

- if read data is available on the ssh socket, how do cause it to be
read (_libssh2_transport_read() ?) so that I can see what channel(s)
have data?

- after available data is read from the ssh socket (somehow), is there
an api to see which channels have data available?

It would seem to me that I need something like
"libssh2_channel_read_channels()" that does _libssh2_transport_read()
and then returns a list of channels that have packets in
session->packets. That way, I could follow up with
libssh2_channel_read() for each channel where I have the target write
socket ready in the select write set.

With the current API, it seems that the approach would be to do the
select() and if the ssh socket was set for read to do a
libssh2_channel_read() for each channel where the target write socket
is ready. This would seem to me to be less efficient, but it also
doesn't prioritize the channel data FIFO. Perhaps I'm making too
much of it.

Any advice or suggestions would be appreciated.

Kirk Wolf
Dovetailed Technologies
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2012-08-14

the libssh2 team