Dimon
Авг. 15, 2007 18:35:53
Приветствую всех! Создаю серверное приложение, которое использует неблокирующие сокеты. Возникает проблема - обработка ошибок. При принятии данных всё просто: в цикле смотрим - пришли ли нам какие-то данные, или нет:
while 1:
try:
data=Connect.recv(256)
except socket.error, (errno, strerror):
if errno==10035: #Ошибка, когда нет данных
data=''
else:
log.error(“Socket error %s: %s” % (errno,strerror))
А вот с отправкой данных разобраться не могу:
try:
Connect.send(“Wow!”)
except socket.error, (errno, strerror):
log.error(“Socket error %s: %s” % (errno,strerror))
Такая конструкция выведет ошибку только в том случае, если сокет недоступен в момент отправки. Если же ошибка возникнет позже в процессе передачи данных, эта конструкция не поможет. нужно как-то узнать статус сокета - успешно ли отправились данные. Куда копать? Кто может помочь? Блокирующие сокеты использовать нет возможности.
Dimon
Авг. 16, 2007 07:18:14
select тут не совсем подойдет. select позволит узнать, смогу ли я отправить данные в сокет, или нет. но try - send - except тут будет более удобным - я сразу узнаю причину, по которой отправка невозможна. select пригодился бы, если у меня в наличии было бы несколько сокетов, а у меня все сокеты обрабатываются отдельно, т.е. в единицу времени я обрабатываю один сокет, и не важно - готов он, или нет.
На одном из сайтов прочитал, что даже блокирующий send не дает гарантии, что данные успешно дошли до клиента, а, значит, и проверку делать не стоит. Я решил, что буду отправлять данные, и если ошибки сразу не произошло, то буду считать, что данные отправлены успешно и буду ждать ответа от клиента. Наверно, так правильно.. :)
slivlen
Авг. 16, 2007 09:07:18
Dimon
На одном из сайтов прочитал, что даже блокирующий send не дает гарантии, что данные успешно дошли до клиента, а, значит, и проверку делать не стоит.
Причем здесь send? Все зависит от выбора транспортного протокола. Если используется
tcp, то доставка гарантируется, если
udp - нет.
redixin
Авг. 16, 2007 10:05:18
Dimon
select тут не совсем подойдет. select позволит узнать, смогу ли я отправить данные в сокет, или нет.
вот именно. если ОС говорит что ты можешь отправить данные - смело отправляй
естессно данные станут в буфер, и уйдут позже. узнать ушли они или нет - возможно только когда select скажет что можно отправить еще
Dimon
но try - send - except тут будет более удобным - я сразу узнаю причину, по которой отправка невозможна
смотря что ты пишешь, если это чтото вроде реактивной системы то удобнее будет select, даже в случае с одним сокетом
Dimon
в единицу времени я обрабатываю один сокет, и не важно - готов он, или нет.
вот это вот какраз и важно, если сокет не готов то у тебя выскочит exception. зачем насиловать сокет если можно просто узнать хочет ли он?
Dimon
На одном из сайтов прочитал, что даже блокирующий send не дает гарантии, что данные успешно дошли до клиента
никто не дает гарантии что данные дошли, клиент может отвалиться в любой момент. не нужно быть гением чтобы это понять