[Qt-interest] qt sockets vs native sockets and libssh2

Dmitry Teslenko dteslenko at gmail.com
Tue Jan 11 13:51:22 CET 2011


Hello!
I'm trying to get ssh port forwarding with libssh2 and qt4 gui on win32
platform.
SSH library provides usable example with native sockets and I have
problem adapt that code for qt sockets.
libssh2 works fine with native sockets work and stucks on data transfer
with qt sockets. I guess there's some kind of restriction in libssh2 or
in qt that I dont' aware of and I need your help.

I'll birefly explain here socket manipulations and attach compileable
examples.


1) native sockets

    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
	...

    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    if (connect(sock, (struct sockaddr*)(&sin),
	...
    session = libssh2_session_init();
	...
    listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(local_listenport);
	...
    sockopt = 1;
    setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
    sinlen=sizeof(sin);
    if (-1 == bind(listensock, (struct sockaddr *)&sin, sinlen)) {
		...
    if (-1 == listen(listensock, 2)) {
		...
    forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
	...
    channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
        remote_destport, shost, sport);
	...
    libssh2_session_set_blocking(session, 0);
	...
	//data transfer
    while (1) {
        FD_ZERO(&fds);
        FD_SET(forwardsock, &fds);
        tv.tv_sec = 0;
        tv.tv_usec = 100000;
        rc = select(forwardsock + 1, &fds, NULL, NULL, &tv);
        if (-1 == rc) {
			...
        if (rc && FD_ISSET(forwardsock, &fds)) {
            len = recv(forwardsock, buf, sizeof(buf), 0);
            if (len < 0) {
				...
            wr = 0;
            do {
                i = libssh2_channel_write(channel, buf, len);
                if (i < 0) {
					...
                wr += i;
            } while(i > 0 && wr < len);
        }
        while (1) {
            len = libssh2_channel_read(channel, buf, sizeof(buf));
            if (LIBSSH2_ERROR_EAGAIN == len)
                break;
            else if (len < 0) {
				...
            wr = 0;
            while (wr < len) {
                i = send(forwardsock, buf + wr, len - wr, 0);
                if (i <= 0) {
					...
                wr += i;
            }
            if (libssh2_channel_eof(channel)) {
				...
        }
    }

2) qt sockets

	QTcpSocket socket;
	socket.connectToHost(...);
	if(!socket.waitForConnected())
		...
	LIBSSH2_SESSION *session = libssh2_session_init();
	...
	rc = libssh2_session_startup(session, socket.socketDescriptor());
	...

	QTcpServer *server = new QTcpServer;
	connect(server, SIGNAL(newConnection()), this, SLOT(openConnection()));
	if(!server->listen(...))
	...
	//in openConnection()

		QTcpServer *server = static_cast<QTcpServer *>(sender());
		QTcpSocket *socket = server->nextPendingConnection();
		...
		LIBSSH2_CHANNEL *channel = libssh2_channel_direct_tcpip_ex(
			m_session,
			tunnel.m_host.toLocal8Bit().constData(),
        	tunnel.m_hostPort,
			server->serverAddress().toString().toLocal8Bit().constData(),
			server->serverPort()	
		);
	//data transfer
		char buffer[4096];
				QTcpSocket *socket = ... //from nextPendingConnection
				LIBSSH2_CHANNEL *channel = ...

				libssh2_channel_set_blocking(channel, 0);

				int read = socket->read(buffer, sizeof(buffer));
				int written = 0;
				int i = 0;
				if(read > 0)
				{
					do
					{
						i = libssh2_channel_write(
							channel,
							buffer,
							read
						);
						if(i < 0)
							...
						written += i;
					} while (i > 0 && written < read);
				}

				while(true)
				{
					read = libssh2_channel_read(channel, buffer, sizeof(buffer));
					if(LIBSSH2_ERROR_EAGAIN == read)
						break
						...
					else if(read  < 0)
						...
					written = 0;
					while(written < read)
					{
						i = socket->write(buffer + written, read - written);
						if(i < 0)
							...
						written += i ;
					}

					if (libssh2_channel_eof(channel)) {
						...
				}


SSH auth works fine and I've omitted it. Program stucks on  data transfer.
libssh2_channel_read returns LIBSSH2_ERROR_EAGAIN forever with qt sockets.

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: direct_tcpip.c
Type: text/x-csrc
Size: 8408 bytes
Desc: not available
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110111/7fca1b58/attachment.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: qt.cpp
Type: text/x-c++src
Size: 14151 bytes
Desc: not available
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110111/7fca1b58/attachment-0001.bin 


More information about the Qt-interest-old mailing list