talking between python tcp server and a c++ client - c++

I am having an issue trying to communicate between a python TCP server and a c++ TCP client.
After the first call, which works fine, the subsequent calls cause issues.
As far as WinSock is concerned, the send() function worked properly, it returns the proper length and WSAGetLastError() does not return anything of significance.
However, when watching the packets using wireshark, i notice that the first call sends two packets, a PSH,ACK with all of the data in it, and an ACK right after, but the subsequent calls, which don't work, only send the PSH,ACK packet, and not a subsequent ACK packet
the receiving computers wireshark corroborates this, and the python server does nothing, it doesnt have any data coming out of the socket, and i cannot debug deeper, since socket is a native class
when i run a c++ client and a c++ server (a hacked replica of what the python one would do), the client faithfully sends both the PSH,ACk and ACK packets the whole time, even after the first call.
Is the winsock send function supposed to always send a PSH,ACK and an ACK?
If so, why would it do so when connected to my C++ server and not the python server?
Has anyone had any issues similar to this?

client sends a PSH,ACK and then the
server sends a PSH,ACK and a
FIN,PSH,ACK
There is a FIN, so could it be that the Python version of your server is closing the connection immediately after the initial read?
If you are not explicitly closing the server's socket, it's probable that the server's remote socket variable is going out of scope, thus closing it (and that this bug is not present in your C++ version)?
Assuming that this is the case, I can cause a very similar TCP sequence with this code for the server:
# server.py
import socket
from time import sleep
def f(s):
r,a = s.accept()
print r.recv(100)
s = socket.socket()
s.bind(('localhost',1234))
s.listen(1)
f(s)
# wait around a bit for the client to send it's second packet
sleep(10)
and this for the client:
# client.py
import socket
from time import sleep
s = socket.socket()
s.connect(('localhost',1234))
s.send('hello 1')
# wait around for a while so that the socket in server.py goes out of scope
sleep(5)
s.send('hello 2')
Start your packet sniffer, then run server.py and then, client.py. Here is the outout of tcpdump -A -i lo, which matches your observations:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes
12:42:37.683710 IP localhost:33491 > localhost.1234: S 1129726741:1129726741(0) win 32792 <mss 16396,sackOK,timestamp 640881101 0,nop,wscale 7>
E..<R.#.#...............CVC.........I|....#....
&3..........
12:42:37.684049 IP localhost.1234 > localhost:33491: S 1128039653:1128039653(0) ack 1129726742 win 32768 <mss 16396,sackOK,timestamp 640881101 640881101,nop,wscale 7>
E..<..#.#.<.............C<..CVC.....Ia....#....
&3..&3......
12:42:37.684087 IP localhost:33491 > localhost.1234: . ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..4R.#.#...............CVC.C<......1......
&3..&3..
12:42:37.684220 IP localhost:33491 > localhost.1234: P 1:8(7) ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..;R.#.#...............CVC.C<......./.....
&3..&3..hello 1
12:42:37.684271 IP localhost.1234 > localhost:33491: . ack 8 win 256 <nop,nop,timestamp 640881102 640881102>
E..4.(#.#...............C<..CVC.....1}.....
&3..&3..
12:42:37.684755 IP localhost.1234 > localhost:33491: F 1:1(0) ack 8 win 256 <nop,nop,timestamp 640881103 640881102>
E..4.)#.#...............C<..CVC.....1{.....
&3..&3..
12:42:37.685639 IP localhost:33491 > localhost.1234: . ack 2 win 257 <nop,nop,timestamp 640881104 640881103>
E..4R.#.#...............CVC.C<......1x.....
&3..&3..
12:42:42.683367 IP localhost:33491 > localhost.1234: P 8:15(7) ack 2 win 257 <nop,nop,timestamp 640886103 640881103>
E..;R.#.#...............CVC.C<......./.....
&3%W&3..hello 2
12:42:42.683401 IP localhost.1234 > localhost:33491: R 1128039655:1128039655(0) win 0
E..(..#.#.<.............C<......P...b...
9 packets captured
27 packets received by filter
0 packets dropped by kernel

What size of packets do you send?
If they are small - may be Nagle's Algorith & Delayed ACK Algorithm is your headache? From what you described think Delayed ACK is involved...

Related

Sometime Disconnect Req is inside Publish Message

On the client side I use:
mosquitto_pub -t tpc -m msg
On the server side I use nonblocking socket and socket() API:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzab6/xnonblock.htm
After first received packet I send connect acknowledge packet.
For each received packet I print how many bytes was received and whole buffer in hex.
I compare received data with WireShark capturing.
Sometime it works well:
37 bytes received - Connect Command
10 bytes received - Publish Message [tpc]
2 bytes received - Disconnect Req
Sometime I get Disconnect Req inside Publish Message [tpc]:
37 bytes received - Connect Command
12 bytes received - Publish Message [tpc] + Disconnect Req
These last two bytes are Disconnect Req:
30
8
0
3
74
70
63
6d
73
67
ffffffe0 <--
0 <--
How can I avoid these situations and get always 3 packets?
Short answer: you can't. You have to actually parse the messages to determine the length.
The constant to create a tcp socket is called SOCK_STREAM for a reason. Socket has to be treated as such: a stream of bytes. Nobody guarantees that one send() on one side results in one recv() on the other side. The only guarantee is that the sequence is preserved: abcd may become (ab, cd), but will not become acbd.
The packets may be splitted somewhere half the way. So it may be that the client sends 2048 bytes, but on the server side you'll receive first ~1400 bytes and then the rest. So N sends does not result in N recv.
Another thing is that the client also treats the socket as a stream. It may send byte by byte, or send a batch of messages with one send(). N messages are not N sends.

Why DPDK only cannot send and receive 60 bytes packet

I have written a simple DPDK send and receive application. When the packet len <= 60 bytes, send and receive application works, but when packet len > 60 bytes, send application show it has sent out packet. but in recieve application, it does not receive anything.
In send application:
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
pkt = rte_pktmbuf_alloc(mbuf_pool);
pkt->data_len = packlen; //if packlen<=60, it works, but when packlen>60, receiver cannot receive anything.
I try both l2fwd and basicfwd as receive application. It is same result.
The issue is here:
pchar[12]=0;
pchar[13] = 0
This means Ethertype is 0. From the list of assigned Ethertypes:
https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
We see that 0 means zero Ethernet frame length. Since the minimum Ethernet frame length is 64 (60 + 4 FCS), that is why you have troubles sending packets longer that 60 bytes.
To fix the issue, simply put there a reasonable Ethertype from the list above.

Python Sockets: Can only send/receive a message once

Whenever I send a message from my client to the server (or vice versa), I have to wait until I've sent a message from the other side for it to register.
server.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
while True:
message = raw_input("Send message: ")
s.send(message)
print s.recv(1024)
client.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.bind((host, port))
s.listen(5)
c,addr = s.accept()
while True:
message = raw_input("Send message: ")
c.send(message)
print c.recv(1024)
Example:
server sends message
nothing happens on client side
client sends message
both server and client receive their messages
this will happen over and over
Well, it's obvious that you have to wait for "the other side" because you have raw_input calls sitting in your code that are waiting for the user to type something...
That said, you're also recv'ing 1024 bytes but sending much less, probably. Thus the recv() will usually hang until it has enough data (but not always, in which case it returns less). Remember that with lowlevel socket communication you have to properly take care of message sizes/boundaries yourself!
You can agree on a termination byte such as "\n" that signifies the boundary between messages, or another strategy is to prepend every message by a few bytes that signify the size of the message following it. You then recv() exactly that amount. Or just send a fixed amount of data for every message.
What remains is that you still have to deal with the fact that send() and recv() sometimes don't send or receive everything: they have a return value that is important. Using sendall, and recv with the MSG_WAITALL flag can take care of most issues, but there's no guarantee.
Read this https://docs.python.org/3/howto/sockets.html#using-a-socket for starters.

TCP Connection Dropped [duplicate]

I am using a loop to read message out from a c Berkeley socket but I am not able to detect when the socket is disconnected so I would accept a new connection. please help
while(true) {
bzero(buffer,256);
n = read(newsockfd,buffer,255);
printf("%s\n",buffer);
}
The only way you can detect that a socket is connected is by writing to it.
Getting a error on read()/recv() will indicate that the connection is broken, but not getting an error when reading doesn't mean that the connection is up.
You may be interested in reading this:
http://lkml.indiana.edu/hypermail/linux/kernel/0106.1/1154.html
In addition, using TCP Keep Alive may help distinguish between inactive and broken connections (by sending something at regular intervals even if there's no data to be sent by the application).
(EDIT: Removed incorrect sentence as pointed out by #Damon, thanks.)
Your problem is that you are completely ignoring the result returned by read(). Your code after read() should look at least like this:
if (n == 0) // peer disconnected
break;
else if (n == -1) // error
{
perror("read");
break;
}
else // received 'n' bytes
{
printf("%.*s", n, buffer);
}
And accepting a new connection should be done in a separate thread, not dependent on end of stream on this connection.
The bzero() call is pointless, just a workaround for prior errors.
That's because you didn't use keepalive timeout.
In receiving side, keepalive socket option is the best solution for detecting dead connection.
But, in case of your application continue to write to socket, there is something to think more.
Even though you already set keepalive option to your application socket, you can't detect in time the dead connection state of the socket, in case of your app keeps writing on the socket.
That's because of tcp retransmission by the kernel tcp stack.
tcp_retries1 and tcp_retries2 are kernel parameters for configuring tcp retransmission timeout.
It's hard to predict precise time of retransmission timeout because it's calculated by RTT mechanism.
You can see this computation in rfc793. (3.7. Data Communication)
https://www.rfc-editor.org/rfc/rfc793.txt
Each platforms have kernel configurations for tcp retransmission.
Linux : tcp_retries1, tcp_retries2 : (exist in /proc/sys/net/ipv4)
http://linux.die.net/man/7/tcp
HPUX : tcp_ip_notify_interval, tcp_ip_abort_interval
http://www.hpuxtips.es/?q=node/53
AIX : rto_low, rto_high, rto_length, rto_limit
http://www-903.ibm.com/kr/event/download/200804_324_swma/socket.pdf
You should set lower value for tcp_retries2 (default 15) if you want to early detect dead connection, but it's not precise time as I already said.
In addition, currently you can't set those values only for single socket. Those are global kernel parameters.
There was some trial to apply tcp retransmission socket option for single socket(http://patchwork.ozlabs.org/patch/55236/), but I don't think it was applied into kernel mainline. I can't find those options definition in system header files.
For reference, you can monitor your keepalive socket option through 'netstat --timers' like below.
https://stackoverflow.com/questions/34914278
netstat -c --timer | grep "192.0.0.1:43245 192.0.68.1:49742"
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (1.92/0/0)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (0.71/0/0)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (9.46/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (8.30/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (7.14/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (5.98/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (4.82/0/1)
In addition, when keepalive timeout ocurrs, you can meet different return events depending on platforms you use, so you must not decide dead connection status only by return events.
For example, HP returns POLLERR event and AIX returns just POLLIN event when keepalive timeout occurs.
You will meet ETIMEDOUT error in recv() call at that time.
In recent kernel version(since 2.6.37), you can use TCP_USER_TIMEOUT option will work well. This option can be used for single socket.

Server not receiving UDP packets, been spending hours trying to figure out what's wrong

So for our first assignment we made a basic ftp program using TCP, now we have to modify it to use UDP, also sending it to a router program (that we cannot modify, but have the code to look at) that will randomly drop and delay packets and handle it with a simple stop and wait protocol. But that's not the problem.
I modified the Client and Server to use UDP using the notes from my lab teacher (http://www.cs.concordia.ca/~ste_mors/comp445/Assign2tutorial.ppt) and all I'm doing is sending a packet and when I receive it on the other end print a line of text. I followed the instructions in the slides, running it on localhost (have no other machines to test with) and it sends, and the router confirms it receives and forwards the packet, but the server never prints the line of text. Knowing that UDP drops packets a lot I made a while(true) loop that sends packets forever, the server still does nothing.
Here's the code so far:
Client: http://pastebin.com/XdbxuJ9R
Server: http://pastebin.com/iN5j2Ku3
Unmodifiable Router given to us: http://pastebin.com/QwMAc0MW
For the client i left in everything after the connection starts from the old one, the send line is 175, in server I commented out everything in the run loop except the receive part which is at line 181
I'm going absolutely crazy trying to fix this. I had to cancel plans and ruin my entire day because I can't get this one thing working. :(
From what i can tell you're using the wrong ports. Here's what the router.h defines:
// router.h
#define ROUTER_PORT1 7000 //router port number 1
#define ROUTER_PORT2 7001 //router port number 2
#define PEER_PORT1 5000 //port number of peer host 1
#define PEER_PORT2 5001 //port number of peer host 2
And here's what you're defining:
// client.cpp
#define REQUEST_PORT 0x5000 // hexadecimal, that's port 20480
and
// server.cpp
#define REQUEST_PORT 0x5001 // hexadecimal, that's port 20481
I didn't check the rest of the code, but the server appeared to receive something after correcting the port numbers (as in removing the 0x prefix)
Maybe this will help illustrate how the router works:
// the router does (pseudocode):
recvfrom(7000), sendto(PEER2:5001)
recvfrom(7001), sendto(PEER1:5000)