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

Christian Gagneraud cgagneraud at techworks.ie
Tue Jan 11 15:05:50 CET 2011


On 01/11/2011 12:51 PM, Dmitry Teslenko wrote:
> 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.

Why don't you don't simply fork a SSH process (using QProcess) that do 
the port forwarding for you?

My 2 cents.
Chris



>
> 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.
>
>
>
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest


-- 
Christian Gagneraud,
Electronics and software engineer

TechWorks Marine Ltd
4a, Park Lane
Dun Laoghaire, Co Dublin
Ireland

Tel: + 353 1 2365990
Fax: + 353 1 2365992
Web: www.techworks.ie





More information about the Qt-interest-old mailing list