Python UDP SocketServer无法读取整个数据包

时间:2014-10-15 22:10:56

标签: python sockets networking udp bufferedreader

在发件人方面,我使用处理语言(部分代码)使用以下代码:

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();
  }
}

在接收方,我正在使用SocketServer python结构来设置监听udp数据报的服务器,如下所示。

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()

编辑: 我特别在使用timeConstructor(data [2:9])时遇到问题,因为我正在访问索引数据,有时(借助print)我无法从第二个字节接收< em> data ,有一次它让我脱离了索引,因为我没有收到分钟第二个。大多数情况下代码运行良好,但这种类型的错误让我很好奇。

旧: 问题是当读取有效负载时,有时似乎有些字节没有到达,即使我使用Wireshark捕获了整个有效负载(但是Wireshark没有告诉我这是发送的数据包还是收到的数据包因为我正在使用loopback接口,也许是重复的信息?)。如果数据报有16个字节的有效载荷长,有时我收到15,因为从数据解析时我得到了索引错误。 我认为有一些缓冲问题。不是吗?如何正确配置?我知道由于无连接协议我可以丢包,但我不认为字节丢失了。假设“ data ”具有来自一个udp数据报的所有有效载荷数据。

1 个答案:

答案 0 :(得分:0)

我相信你的问题是socket.sendto()并不总是发送你给它的所有字节。它返回发送的字节数,您可能需要再次调用它。打开套接字并调用socket.sendall()

可能会更好