Найти - Пользователи
Полная версия: socket.close() и количество соединений
Начало » Network » socket.close() и количество соединений
1 2
haize
Здравствуйте! Столкнулся с проблемой.

def connect(self):
self.disconnect()
self.link = socket.socket(type = socket.SOCK_DGRAM)
self.link.settimeout(self.timeout)

def disconnect(self):
if self.link:
self.link.close()
self.link = None
Подключаюсь к серверу с помощью connect(). Отправляю n байт. Всё проходит нормально, получаю обратно то, что мне было нужно. Вызываю disconnect().

Всё проходит в цикле, обращаюсь к различным серверам. После вызова disconnect() не происходит разрыва соединения. Если посмотреть количество соединений с помощью файрвола или какого-нибудь network monitor'a обнаруживается, что соединения постоянно растут. После того, как программа завершает работу, количество соединений падает до нуля. Пробовал socket.socket().shutdown() – не помогло.

Помогите, пожалуйста, разобраться в чём проблема. Как мне обрывать соединения после disconnect()?
Андрей Светлов
Это фича. Сокет висит открытым некоторое время после close(). Ручки подкрутить это время — нет. Придется с этим жить.
haize
Андрей Светлов
А как же быть, если у меня это реализовано в виде сервера и запросы идут постоянно? Количество соединений вырастает до тысячи очень быстро, что недопустимо для моего приложения.

Сборщик мусора ведь сбрасывает все соединения при завершении программы, или же это ОС закрывает все соединения после завершения скрипта? Есть какой-нибудь выход из этой ситуации?
Enchantner
Андрей Светлов
а разве REUSEADDR не для этого? Или он только для TCP?

haize
Попробуйте сделать через какой-нибудь pycurl. Возможно, что даже многопоточно получится. И да, еще есть вариант - использовать gevent, там своя обертка на сокет и легкие юзерспейс-треды.
Андрей Светлов
Извините, просмотрел. У вас же UDP сокеты. Так зачем вы их каждый раз заново создаете?
Андрей Светлов
Enchantner, REUSEADDR именно для TCP, причем серверного. Т.е. при .connect он не поможет.
haize
Андрей Светлов
Каждый раз я подключаюсь к серверам с разными IP адресами и портами. Можно как-то переподключиться к другому серверу не вызывая создавая нового экземпляра сокета и не вызывая функцию socket.socket().connect()?
Подскажите, пожалуйста, как будет правильно поступить в этом случае?
Андрей Светлов
У вас UDP? Так используйте sendto/recvfrom.
haize
Андрей Светлов
У вас UDP? Так используйте sendto/recvfrom.
Да. Пробовал сегодня вместо socket.connect((self.host, self.port)) сразу отправлять данные с помощью socket.sendto.

В цикле обхожу кортеж со значениями ip-адреса и порта и выполняю socket.sendto.

Что-то, типа:
soc = socket.socket(type = socket.SOCK_DGRAM)
for ip, port in server_list:
soc.sendto(data, (ip, port))
res = soc.recv(packet_size)
# -- код выполняющий обработку ответа --
Количество соединений постоянно растёт и почти не падает. Точно так же, как и с socket.connect и socket.send. Как сделать правильно?
Андрей Светлов
Без полного работающего кода гадаю по пятнам света от проезжающих мимо окна машин.
Зачем вам soc.recv — нужно делать soc.recvfrom.
И вы всё ещё создаёте сокет на каждый запрос?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB