2016-09-19 5 views
1

recv не работает должным образом. Я отправляю 10 байтов (проверено с помощью wirehark), а recv только получает первый байт и отбрасывает остальные (до следующего отправления). Это многоадресная вещь? Я почти уверен, что сделал то же самое с одноадресным UDP и не имел никаких проблем.Python recv multicast возвращает один байт

Вот мой пример кода:

import struct, socket, multiprocessing, time 

MCAST_PORT = 62950 
MCAST_GRP = '239.0.0.13' 

def _Rx(self, RXsock, Queue): 
    print "Receiver started" 
    while True: 
     # State machine goes here to parse header and recv (<msglen>) bytes. 
     print "Waiting Rx char...", RXsock 
     char = RXsock.recv(1) # Blocks here after first byte ("1") ??? 
     print "Rx", hex(ord(char)) 



TXsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
TXsock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) 

RXsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
RXsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
RXsock.bind((MCAST_GRP, MCAST_PORT)) 
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 
RXsock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 

RxQueue = multiprocessing.Queue() 
receiver = multiprocessing.Process(target=_Rx, args=(None, RXsock, RxQueue)) 
receiver.daemon = True 
receiver.start() 


TXsock.sendto("09123456789", (MCAST_GRP, MCAST_PORT)) 
time.sleep(3) 
+0

Возможно, связанный: http://stackoverflow.com/questions/2862071/how-large-should-my-recv-buffer-be-when-calling-recv-in-the-socket-library (потому что его дейтаграмма) – Caramiriel

ответ

1

Вы только получаете один байт, так как вы установите размер буфера в один.

От documentation for socket.recv:

Максимальный объем данных, которые должны быть получены сразу же задается BUFSIZE.

Попробуйте прохождение 1024 или 4096 к recv.

От man page for recv:

Если сообщение слишком длинное, чтобы поместиться в указанный буфер, лишние байты могут быть отброшены в зависимости от типа сокета, на котором принимаются сообщения.

В вашем комментарии говорится, что вы пытаетесь разобрать заголовок по одному байту за раз. Вы всегда можете разобрать заголовок после того, как вы закончите получать дейтаграмму.

Если вам действительно нужно сделать частичное чтение буфера, попробуйте передавая socket.MSG_PEEK флаг recv:

MSG_PEEK

Этот флаг вызывает операцию приема для возврата данных с начала получить очередь, не удаляя эти данные из очереди. Таким образом, последующий приемный вызов будет возвращать одни и те же данные.

Однако вы по-прежнему не сможете прочитать один байт за раз.

+0

Я установил bufsize в один (1), чтобы я мог разобрать заголовок байтом за раз. Это в цикле while, поэтому он должен возвращать следующий полученный байт на следующем проходе. Когда буфер Rx пуст, он должен блокироваться. Куда делись остальные 9 байт? Кажется, он делает флеш вместе с прочитанным. – Bill

+0

Остальные 9 байтов отбрасываются. См. Выдержку из страницы 'recv' man выше. –

+0

Итак, нет способа сделать чтение частичного буфера? – Bill