PDA

View Full Version : Very strange socket programming problem



montylee
7th November 2008, 05:58
I am using Qt 4.3.4 on Fedora Core 9 and getting a really strange problem.
I have 2 modules, the modules runs on different machines in the network (LAN). Now, when i send some commands from the client module (written using Qt), the server module (written using C) responds through the socket (UDP socket).

Now, i am able to send and receive messages from the client module to the server module and i am also getting the response back from the server to the client. Now, the problem:

In the client Qt GUI, i am sending a command which directs the server to do some task, the task is actually a sequence of steps. The server is supposed to send a acknowledgement to the client after executing each step. The client displays the acknowledgements in the window in a list widget. So, as messages are received from the server, they are displayed in the list widget.
Now, the problem is that server is sending acknowledgements to the client but the client is not able to get any acknowledgements so nothing is displayed in the list widget. I have checked the tcpdump output and it's clear that the client machine is getting the messages from the server but my code is not able to read the messages. I am using processPendingDatagrams () signal to read the messages from the socket. I have checked the bind output and it's ok.

I have another command-line application on the client machine for receiving messages and even that is not able to get the messages sent by the server. So, i guess the problem is not with my GUI (Qt) code.

Another strange thing:
If i manually send messages from server to the client using this code (http://beej.us/guide/bgnet/examples/broadcaster.c) then it's getting displayed in the list widget. Only the messages that are sent by the server application are not getting received by the client code.

Here's the tcpdump output. I am using port 8085 at both client and server side. UDP sockets are being used. Last 3 messages (shown in bold below) in the tcpdump output (were sent manually (using broadcaster.c) and were properly read by the client and displayed in list widget. So, the problem is coming in the rest of the messages that were sent by the server code. In the below output svdu1 is the client and SVDU3 is the server.


# tcpdump port 8085 -xX

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

17:42:42.308413 IP svdu1.50786 > 255.255.255.255.8085: UDP, length 11

0x0000: 4500 0027 0000 4000 4011 0b35 0a70 2522 E..'..@.@..5.p%"

0x0010: ffff ffff c662 1f95 0013 9767 6c6f 675f .....b.....glog_

0x0020: 6c65 7665 6c3d 30 level=0

17:42:49.570692 IP svdu1.37028 > 255.255.255.255.8085: UDP, length 11

0x0000: 4500 0027 0000 4000 4011 0b35 0a70 2522 E..'..@.@..5.p%"

0x0010: ffff ffff 90a4 1f95 0013 cc25 6c6f 675f ...........%log_

0x0020: 6c65 7665 6c3d 31 level=1

17:42:49.571166 IP svdu1.58360 > SVDU3.8085: UDP, length 11

0x0000: 4500 0027 0000 4000 4011 db61 0a70 2522 E..'..@.@..a.p%"

0x0010: 0a70 2563 e3f8 1f95 0013 7a21 7665 7273 .p%c......z!vers

0x0020: 696f 6e3d 302e 32 ion=0.2

17:42:49.571419 IP SVDU3.8085 > svdu1.58360: UDP, length 1

0x0000: 4500 001d 0000 4000 4011 db6b 0a70 2563 E.....@.@..k.p%c

0x0010: 0a70 2522 1f95 e3f8 0009 68e9 3400 0000 .p%"......h.4...

0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............

17:42:49.592617 IP svdu1.58360 > 255.255.255.255.8085: UDP, length 1

0x0000: 4500 001d 0000 4000 4011 0b3f 0a70 2522 E.....@.@..?.p%"

0x0010: ffff ffff e3f8 1f95 0009 99bc 33 ............3

17:42:49.639840 IP SVDU3.8085 > svdu1.58360: UDP, length 1

0x0000: 4500 001d 0000 4000 4011 db6b 0a70 2563 E.....@.@..k.p%c

0x0010: 0a70 2522 1f95 e3f8 0009 6ce9 3000 0000 .p%"......l.0...

0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............

17:42:50.641212 IP SVDU3.8085 > svdu1.58360: UDP, length 36

0x0000: 4500 0040 0000 4000 4011 db48 0a70 2563 E..@..@.@..H.p%c

0x0010: 0a70 2522 1f95 e3f8 002c 700b 2849 443a .p%".....,p.(ID:

0x0020: 2031 2920 4576 656e 7420 7375 6363 6573 .1).Event.succes

0x0030: 7366 756c 6c79 2073 696d 756c 6174 6564 sfully.simulated

17:42:52.714828 IP SVDU3.8085 > svdu1.58360: UDP, length 17

0x0000: 4500 002d 0000 4000 4011 db5b 0a70 2563 E..-..@.@..[.p%c

0x0010: 0a70 2522 1f95 e3f8 0019 6569 506c 6179 .p%"......eiPlay

0x0020: 6261 636b 2066 696e 6973 6865 6400 back.finished.

17:42:57.368340 IP SVDU3.1049 > svdu1.8085: UDP, length 5

0x0000: 4500 0021 0000 4000 4011 db67 0a70 2563 E..!..@.@..g.p%c

0x0010: 0a70 2522 0419 1f95 000d 38ef 6865 6c6c .p%"......8.hell

0x0020: 6f00 0000 0000 0000 0000 0000 0000 o.............

17:43:02.302689 IP SVDU3.1049 > svdu1.8085: UDP, length 6

0x0000: 4500 0022 0000 4000 4011 db66 0a70 2563 E.."..@.@..f.p%c

0x0010: 0a70 2522 0419 1f95 000e 38bc 6865 6c6c .p%"......8.hell

0x0020: 6f31 0000 0000 0000 0000 0000 0000 o1............

17:43:05.027988 IP SVDU3.1049 > svdu1.8085: UDP, length 6

0x0000: 4500 0022 0000 4000 4011 db66 0a70 2563 E.."..@.@..f.p%c

0x0010: 0a70 2522 0419 1f95 000e 38bb 6865 6c6c .p%"......8.hell

0x0020: 6f32 0000 0000 0000 0000 0000 0000 o2............


12 packets captured
12 packets received by filter
0 packets dropped by kernel

Script done on Monday 03 November 2008 05:43:13 PM IST

I found a strange thing in the above output:
Messages sent by the server code are shown as:
SVDU3.8085 > svdu1.58360

whereas messages sent manually using broadcaster.c are shown as:
SVDU3.1049 > svdu1.8085

I am not sure what svdu1.58360 means because from the server code, i am sending messages to the 8085 port.

Actually, even when i successfully receive messages from the server to the client, these ports are shown different (i.e. other than 8085).

wysota
7th November 2008, 10:45
Are you certain both the client and the server use the port 8085? Could you check with netstat or something similar? "svdu1.58360" suggests it is using a different port.

montylee
7th November 2008, 11:52
Actually as i said i am using port 8085 at both ends. I have no idea why tcpdump shows different ports. Even when i get messages from the server properly tcpdump shows different ports.

Ok i found out 1 thing:

My client GUI code written in Qt calls a C API in a C file, the C API actually sends the command to the server, the server responds back with some message which is properly received by the C code. Now, there are 2-3 messages exchanged between the C code and server. All these messages are received properly.

Now, when the command is properly started at the server side, at the client side the control is passed from the C code to GUI code. Here is when i am getting the problem. As soon as i get the control back in GUI code, i create a new window with a list widget to display the messages. This window is a new class which creates a socket, binds it to port 8085 and starts listening to the port. I have trapped readyRead() signal to read the messages from the socket and add the messages to the list widget.

After this i start getting messages at port 8085 from the server as shown by the tcpdump output but readyRead() signal is not being sent and the list widget is not updated.

Now, i found a new thing. In the C code at client side, instead of sending the control back to the GUI code immediately, i did a recvfrom() again at the socket and i was able to get the message sent by the server. So, the problem is that as soon as i pass the control back to the GUI code and start listening to the socket i am unable to receive any messages. If i continue listening to messages in the C code itself, i am getting the messages.

I don't know why i am getting this problem. Only the messages sent by the server are not received by the GUI code, manual messages sent by broadcaster.c are properly received.

Please suggest something... I think i may have to find a way to continue reading messages in the C code and passing those messages to the GUI code so that they are properly displayed in the list widget but still i would like to make the existing code work. I have no idea why the GUI is not able to get the messages whereas the C code is getting the messages. Even the other command-line code is not able to get the message so i am thinking that maybe my C code is not closing the socket properly so it is not allowing any other application to read the socket. But i have called close() on the socket descriptor.

montylee
8th November 2008, 20:00
please help me. I am thinking of getting the messages in the C code itself and passing each message back to the GUI code.
What is the best possible way of doing this? I need to pass each message received in C code to the GUI so that it gets displayed in the GUI. The C code should keep executing and listening to the socket, as soon as it gets a message it should be sent to the GUI code and the C code should continue listening to the socket.

bhs-ittech
10th November 2008, 10:52
just a wild guess, but can your C code send back the socket descriptor to the GUI code, and then let Qt close the socket?

then perhaps you can do something like this:


int sd = C_CodeFunction();
QUdpSocket *udp = new QUdpSocket;
if(udp->setSocketDescriptor(sd))
{
QObject::connect(udp, SIGNAL(readyRead()), your_obj, SLOT(your_slot()));
}


or something to that effect.

montylee
11th November 2008, 12:05
just a wild guess, but can your C code send back the socket descriptor to the GUI code, and then let Qt close the socket?

then perhaps you can do something like this:


int sd = C_CodeFunction();
QUdpSocket *udp = new QUdpSocket;
if(udp->setSocketDescriptor(sd))
{
QObject::connect(udp, SIGNAL(readyRead()), your_obj, SLOT(your_slot()));
}


or something to that effect.

wow!!! it worked :) I can't believe that your suggestion worked. I just passed the socket descriptor from C code to the Qt code and i am now able to read all messages in the Qt code.

Thanks a lot for replying and helping me in this issue :)

I still have no idea why i was not able to create a new socket and read the messages earlier.