[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Socket communitation gives surprising results.
From:       Erik Sigra <sigra () home ! se>
Date:       2002-10-06 9:57:09
[Download RAW message or body]

I made a small testcase for communication with KExtendedSocket and 
QDataStream. I got surprising results. The client application is using 
adasockets and the server application is using KDE.

I also have a client in python that gives the same surprising result. This 
shows that the problem is on the server (KDE) side, and not on the client 
(Ada, Python) side.

First the client sends a byte to the server. When the server gets the byte, it 
replies with 2 strings:

			The_Stream << "ABC";
			The_Stream << "DEF";

I made the client read the strings character by character. This is what it 
received:

Block  0:                  #  It seems that Qt uses 4 bytes to
 0 received '' ( 0)        #  transmit the length of the string.
 1 received '' ( 0)        #  That seems reasonable.
 2 received '' ( 0)
 3 received '' ( 4)

Block  1:                  #  Here comes the first string with the
 0 received 'A' ( 65)      #  null terminator.
 1 received 'B' ( 66)      #  That seems reasonable too.
 2 received 'C' ( 67)
 3 received '' ( 0)

Block  2:                  #  Here comes the length of the second
 0 received '' ( 0)        #  string.
 1 received '' ( 0)
 2 received '' ( 0)
 3 received '' ( 4)

Block  3:
 0 received 'D' ( 68)      #  Here comes the second string with the null
 1 received 'E' ( 69)      #  terminator. It is the last thing that the server
 2 received 'F' ( 70)      #  should send, so the client should start waiting
 3 received '' ( 0)        #  now.

Block  4:
 0 received 'A' ( 65)      #  Here it seems that the server has sent the first
 1 received 'B' ( 66)      #  string again! THIS IS UNREASONABLE.
 2 received 'C' ( 67)
 3 received '' ( 0)

Block  5:
 0 received 'D' ( 68)      #  Here comes the second string again! ALSO
 1 received 'E' ( 69)      #  UNREASONABLE.
 2 received 'F' ( 70)
 3 received '' ( 0)

Block  6:
 0 received 'D' ( 68)      #  And here comes the second string yet another
 1 received 'E' ( 69)      #  time! What is happening?
 2 received 'F' ( 70)
 3 received '' ( 0)

Block  7:                  #  Here the client finally starts waiting.


The behaviour is repeatable. An explaination would be 
appreciated. The sorce files are included.


["client.adb" (text/x-adasrc)]

with Sockets.Stream_IO;     use Sockets, Sockets.Stream_IO;
with Ada.Command_Line;      use Ada.Command_Line;
with Ada.Exceptions;        use Ada.Exceptions;
with Ada.Text_IO;           use Ada.Text_IO;
with Ada.Streams;           use Ada.Streams;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;

procedure Client is

   Incoming : Character;
   Block_Number : Natural := 0;

   The_Socket : Socket_FD;
   Stream     : aliased Socket_Stream_Type;

begin

   if Argument_Count /= 2 then
      Raise_Exception
        (Constraint_Error'Identity,
         "Usage: " & Command_Name & " remotehost remoteport");
   end if;
   Socket (The_Socket, AF_INET, SOCK_STREAM);
   --Set_Buffer (The_Socket);
   Connect (The_Socket, Argument (1), Positive'Value (Argument (2)));
   Initialize (Stream, The_Socket);

   --  Send information about this client. Bit 7 requests LittleEndian.
   Character'Write (Stream'Access, Character'Val(2**7));


   loop
      Put_Line ("Block " & Block_Number'Img & ':');
      for I in 0 .. 3 loop
         Character'Read (Stream'Access, Incoming);
         Put_Line
           (I'Img & " received '" & Incoming & "' (" &
            Character'Pos (Incoming)'Img & ')');
      end loop;
      New_Line;
      Block_Number := Block_Number + 1;
   end loop;
end Client;

["Makefile" (text/x-makefile)]

all: server client

server: server.cpp
	/usr/local/qt-x11-free-3/bin/moc server.cpp > server.moc
	g++ -o server server.cpp                                                     \
	  -I/usr/local/qt-x11-free-3/include -L/usr/local/qt-x11-free-3/lib -lqt-mt  \
	  -I/usr/local/kde/include -L/usr/local/kde/lib -lkdecore

client: client.adb
	gnatmake -gnatf client `adasockets-config`

clean:
	@rm -f *.o *.ali *.moc server client gmon.out

["server.cpp" (text/x-c++src)]

#include <kdebug.h>
#include <kextendedsocket.h>
#include <qapplication.h>

class Server : public QObject {
	Q_OBJECT

public:

	Server (unsigned int port) :
		The_Listener (QString::null, port, KExtendedSocket::passiveSocket),
		The_Client (0) {
		kdDebug() << "WAITING FOR CONNECTION\n";
		if (0 == The_Listener.listen()) {
			connect
				(&The_Listener, SIGNAL (readyAccept ()),
         this, SLOT (acceptConnection ()));
		}
		else {
			cerr << "LISTENING FAILED\n";
      exit(1);
	}
	
	}

public slots:

void acceptConnection () {
	if (The_Client == 0) {
		cerr
			<< "The_Listener.accept (The_Client) = "
			<< The_Listener.accept (The_Client) << '\n';
		The_Client->setBufferSize (-1, -1);
		connect (The_Client, SIGNAL (readyRead ()), this, SLOT (readData ()));
		The_Client->enableRead (true);
	}
}

	void readData() {

		assert (The_Client->bytesAvailable ());

		cerr << "the_stream.device() = " << The_Stream.device () << '\n';

		if (The_Stream.device () == 0) {
			//  The connection is new. Read client info. This must be exactly 1 byte.

			const unsigned char client_info = The_Client->getch ();
			cerr
				<< "client_info = "
				<< static_cast<unsigned short int> (client_info) << '\n';


			The_Stream.setDevice(The_Client);

			if (The_Client->bytesAvailable()) {
				cerr
					<< "The client sent some bytes after the info byte. This is not "
					<< "allowed. There are now " << The_Client->bytesAvailable ()
          << " bytes availible\n";
				exit(1);
			}

			The_Stream << "ABC";
			The_Stream << "DEF";
		}
		else {
			Q_UINT8 ch;
			The_Stream >> ch;
			cerr
				<< "Received '" << ch << "' from the client. Will send '" << ch
				<< "'.";
			The_Stream << ch;
		}

	}


private:

	KExtendedSocket The_Listener, * The_Client;
	QDataStream The_Stream;

};

#include "server.moc"

int main (int argc, char **argv) {

	Server The_Server (5678);

	QApplication The_Application (argc, argv);

	return The_Application.exec();
}

["client.py" (text/x-python)]

#! /usr/local/bin/python
#

from socket import *
import sys

s = socket (AF_INET, SOCK_STREAM)
s.connect ((sys.argv[1], eval(sys.argv[2])))
s.send (chr(0x80))
while 1:
	c = s.recv(1)
	print "Received character: %c (%d)" % (c, ord(c))

>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic