0
votes

At sender side I have the following code using processing language (portion code):

udp = new UDP( this, 6002 );  // create a new datagram connection on port 6000
  //udp.log( true );               // <-- printout the connection activity
  udp.listen( true );              // and wait for incoming message 

escribeUDPLog3(1,TRANSMIT,getTime());  //call function

int[] getTime(){
 int year = year();
 int month = month()
 int day = day();
 int hour = hour();
 int minute = minute();
 int second = second();

 int[] time_constructed = {year, month,day,hour,minute,second};
 return time_constructed;
}


void escribeUDPLog3(int pkg_type, int state, int[] time){

short year = (short)(time[0]); //>> 8;
  byte year_msb = byte(year >> 8);
  byte year_lsb = byte(year & 0x00FF);     
  byte month = byte(time[1]);
  byte day = byte(time[2]); 
  byte hour = byte(time[3]); 
  byte minute = byte(time[4]); 
  byte second = byte(time[5]);

  byte[] payload = {byte(pkg_type), byte(state), year_msb, year_lsb, month, day, hour, minute,second};


  try {
    if (UDP5_flag) {udp.send(payload, UDP5_IP, UDP5_PORT);} 
  }  
  catch (Exception e) {
    e.printStackTrace();
  }
}

At receiver side I'm using SocketServer python structure to set up a server listening for udp datagrams, as following.

from datetime import datetime
import csv
import SocketServer

def nodeStateCheckout(nodeid, state, nodeState):
    if (state == ord(nodeState)):
        return "OK"
    else:
        return "FAIL"

def timeConstructor(time):

    year = str(ord(time[0]) << 8 | ord(time[1]))
    month = str(ord(time[2]))
    day = str(ord(time[3]))
    hour = str(ord(time[4]))
    minute = str(ord(time[5]))
    second = str(ord(time[6]))

    time_formatted = year + "-" + month + "-" + day \
                     + " " + hour + ":" + minute + ":" + second

    return time_formatted

class MyUDPHandler(SocketServer.BaseRequestHandler):
    """
    This class works similar to the TCP handler class, except that
    self.request consists of a pair of data and client socket, and since
    there is no connection the client address must be given explicitly
    when sending data back via sendto().
    """

    def handle(self):

        try:

            data = self.request[0].strip()
            socket = self.request[1]
            #print "{} wrote:".format(self.client_address[0])

            pkg_type = ord(data[0])                        

            if pkg_type == 1:       # log 3

                state = ord(data[1])    
                csvfile = open("log3.csv", "a+")
                csvwriter = csv.writer(csvfile, delimiter=',')        
                time_reconstructed = timeConstructor(data[2:9])

                if state == 3:                
                    csvwriter.writerow(["STOP",time_reconstructed])
                elif state == 2:
                    csvwriter.writerow(["START",time_reconstructed])
                else:
                    print "unknown state"

                csvfile.close()                            

            else:
                print "packet not known"

        except IndexError:
            print "Bad parsed byte"                


if __name__ == "__main__":
    HOST, PORT = "localhost", 8892        
    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
    server.serve_forever()

Edited: I have problem specifically when using timeConstructor(data[2:9]), because I'm accessing out of index data, sometimes (with the help of print) I can't received second byte from data, and one time it get me out of index because I didn't received minute and second. Most of the time the code works well, but this type of error get me curious.

Old: The problem is when reading the payload, sometimes its seems that some bytes doesn't arrive, even when I captured the whole payload using Wireshark (but Wireshark didn't tell me if this is the sent packet or received packet because I'm using loopback interfaces, maybe duplicated info?). If the datagram has 16 bytes payload long, sometimes I received 15 because when parsing from data I get out of index error. I think that there are some buffer problems. Isn't it? How to configured it properly? I know that I can get packet loss because of connectionless protocol but I dont think that bytes get lost. It is supposed that "data" has all payload data from one udp datagram.

1

1 Answers

0
votes

I believe your problem is that socket.sendto() does not always send all the bytes that you give it. It returns the number of bytes sent and you may have to call it again. You might be better off with opening the socket yourself and calling socket.sendall()