[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