Hey gang, I don't usually ask programming questions of my own on here, but this one happens to be driving me up one wall and down the other. Consider a C++ program that creates a connecting socket and a Python program with a listening socket. The C++ program and the Python program exchange data over that socket. If both ends send data every once in a while, everything continues to flow smoothly. However, if at some point the C++ end sends a small packet and waits for the remote Python end to do something with the data and send it back, the Python end never gets it. The things I have done:

1) Put the C++ program's send() in a proper loop so it will continue sending until the entire send string is sent.
2) Set both the C++ and PYthon sockets nonblocking
3) Disabled Nagle's algorithm on the C++ (sending) end

The possibilities that I can think of:

1) The C++ (sending) end is still buffering the data, and won't send it until something else is added behind it to kick it into the network. This seems odd.
2) The data's actually getting lost. This seems unlikely.
3) The Python end is getting part of the message, but isn't deciding to expose it to the use. I'm using recv() with a max size of 1024, and it's definitely getting no part of the incoming message

Any ideas? Anything I can do to make sure the sending buffer is flushed or the receiving end dumps out the data? Where do you think the problem is happening? Should I make the receiving end fetch recv() with a max size of 1? That doesn't sound like a good idea. Thanks in advance.

PS - Googling "socket flush C++" yields no end of posts that suggest I'm probably missing a trick somewhere.
I don't know much about Python or C++, but I think the problem is that the Python end isn't handling the data properly.
souvik1997 wrote:
I don't know much about Python or C++, but I think the problem is that the Python end isn't handling the data properly.
Probably. I'm considering trying the recv() call with a 1-byte argument, which is a horrible solution of course, but just to see if it would work; sadly, no other Arduino owners are online now to help me test.
Why not create a temporary program that simulates the Arduino's outputs to your program?
souvik1997 wrote:
Why not create a temporary program that simulates the Arduino's outputs to your program?
I figured it wouldn't be worth it, but maybe I actually should do that at some point. For now, I managed some trickery using Netpong and Chat at the same time along with some well-timed plug-pulling to confirm that the frame is indeed getting stuck somewhere until another piece of data arrives behind it to push it along. Since I was able to do that, I'll switch the Python program to 1-byte receives and see if the same thing happens.

Edit: Whelp, I've confirmed that recv() with a maximum buffer length of 1 does nothing, so the data is getting stuck somewhere before Python.
Alright, I look forward to hearing the results of that. Smile
edit: ninja'd Razz
souvik1997 wrote:
Alright, I look forward to hearing the results of that. Smile
edit: ninja'd Razz
Yeah, I'm a tad disappointed that that wasn't it, since it seemed the most likely to me, but at least that narrows it down. Smile
You know, code snippets would help a great deal here. My guess is you're screwing up your C sockets, since that is very easy to do. The python side is probably correct.

Unless you absolutely need low latency, TCP_NODELAY (aka, disabling Nagle's algorithm) is a pretty bad idea.

Now, my guess as to what is going on isn't a problem with either endpoint, but with the crap in the middle. Many OSes and routers will terminate a TCP session after a long enough delay of nothing happening (hence why things like SSH send keep-alive packets).

But without code (shame on you for that, for reals), all I can do is speculate.

Also, just throwing this out there, but have you considered using a higher level library to handle all this crap for you? Not sure what you're trying to accomplish, but writing directly on top of raw TCP sockets is a massive headache. So much crap to worry about, not to mention platform quirks.
Well, it's for globalCALCnet, and everything's working nicely up to this. I'd be happy to inject keep-alive data of some sort if that's the solution. Here's my sending end:


Code:
   int totalsent = 0;
   int framesize = 3+(int)msgbuf[0]+256*(int)msgbuf[1];
   while(totalsent < framesize) {
      if ((i = send(sd,(char *)(msgbuf+totalsent),framesize-totalsent,0)) < 0) {
      fprintf(stderr,"ERROR writing to socket (%d)\n",errno);
      shutdown(sd);
#ifdef WINDOWS
         WSACleanup();
         closesocket(sd);
#else
         close(sd);
#endif
         exit(0);
      }
      totalsent += i;
   }
   fprintf(stdout,"Wrote %d bytes to socket (frame msg)\n",totalsent);


And here's the Python receiving end:


Code:
                while running:
                        try:
                                data = self.client.recv(self.size)
                                recbuf = recbuf + data
                                recbufqueue += len(data)
                        except socket.error as (errnum,errstr):
                                if errnum == errno.EWOULDBLOCK:
                                        continue;
                                data = 0
                        if data:
                                #self.client.send(data)
                                #print "Received data of length "+str(len(data))+" from "+self.hubname+"."+self.localname
                                while recbufqueue > 2 and recbufqueue >= 3+ord(recbuf[0])+256*ord(recbuf[1]):
                                        thismsglen = ord(recbuf[0])+256*ord(recbuf[1])
                                        thismsg = recbuf[0:3+thismsglen]
                                        self.handlemsg(thismsg)
                                        recbuf = recbuf[3+thismsglen:]
                                        recbufqueue -= 3+thismsglen
                                        if recbufqueue != len(recbuf):
                                                print "[ERROR] buffer length mismatch, discarding buffer"
                                                recbuf = ""
                                                recbufqueue = 0
*bump* Thanks to chatting with Kllrnohj, not only is my code cleaner now, but I happened to notice a ">" that should have been a ">=". Sad Now everything appears to be functioning well, pending testing with Shaun this evening.
Let me know when you need a recompile =)
elfprince13 wrote:
Let me know when you need a recompile =)
Haha, already sent, you ninja'd me. Smile Actually, the problem was in the gCnHub, but I still made improvements to the gCnClient to more reliably handle big frames, so compilation at your leisure would be greatly appreciated.
KermMartian wrote:
elfprince13 wrote:
Let me know when you need a recompile =)
Haha, already sent, you ninja'd me. Smile Actually, the problem was in the gCnHub, but I still made improvements to the gCnClient to more reliably handle big frames, so compilation at your leisure would be greatly appreciated.


You should also try out compilation for Mac and Windows with http://www.sandroid.org/imcross/#What_is_IMCROSS and I can at least see if the Mac binary runs.
Urgh, that looks somewhat painful to me. Smile I'll give it a try, though.
You should post updated code. I'm curious how many of the improvements I suggested you went with.
Kllrnohj wrote:
You should post updated code. I'm curious how many of the improvements I suggested you went with.
Let me do a bit more work on the meat of these two applications to incorporate your suggested changes and clean up code in general before I share that to avoid embarrassing myself. I'll get back to you on this.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement