Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 21, 2009 01:09:06

caribbean_snow
От:
Зарегистрирован: 2009-10-21
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

выбор ip при использовании smtplib

Во первых всем здрасти, рад что попал на этот форум:)

Теперь по делу
На сервере несколько айпишников, при создании объекта SMTP надо как-то указывать определенный интерфейс.
Насколько я понимаю, делать это надо через сокеты, но как я пока не понял.
При использовании urllib2 данную проблему я решил как описано здесь http://stackoverflow.com/questions/1150332/source-interface-with-python-and-urllib2 , т.е. добавив хэндлер.

В какую сторону копать? Альтернатив smtplib с нужным функционалом я не нашел.



Офлайн

#2 Окт. 21, 2009 01:38:58

caribbean_snow
От:
Зарегистрирован: 2009-10-21
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

выбор ip при использовании smtplib

Имхо наследовать класс SMTP и там в функции connect биндить сокет на нужный интерфейс?:)



Офлайн

#3 Окт. 21, 2009 14:21:08

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

выбор ip при использовании smtplib

>>> import smtplib
>>> help(smtplib.SMTP.__init__)
Help on method __init__ in module smtplib:

__init__(self, host='', port=0, local_hostname=None) unbound smtplib.SMTP method
Initialize a new instance.

If specified, `host' is the name of the remote host to which to
connect. If specified, `port' specifies the port to which to connect.
By default, smtplib.SMTP_PORT is used. An SMTPConnectError is raised
if the specified `host' doesn't respond correctly. If specified,
`local_hostname` is used as the FQDN of the local host. By default,
the local hostname is found using socket.getfqdn().

>>> help(smtplib.SMTP.connect)
Help on method connect in module smtplib:

connect(self, host='localhost', port=0) unbound smtplib.SMTP method
Connect to a host on a given port.

If the hostname ends with a colon (`:') followed by a number, and
there is no port specified, that suffix will be stripped off and the
number interpreted as the port number to use.

Note: This method is automatically invoked by __init__, if a host is
specified during instantiation.
local_hostname?

..bw



Офлайн

#4 Окт. 21, 2009 17:29:02

caribbean_snow
От:
Зарегистрирован: 2009-10-21
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

выбор ip при использовании smtplib

local_hostname указывает имя домена а не интерфейс
“If specified,`local_hostname` is used as the FQDN”
дефолтно localhost.localdomain

Не то



Офлайн

#5 Окт. 22, 2009 13:20:09

slivlen
От:
Зарегистрирован: 2006-07-06
Сообщения: 764
Репутация: +  0  -
Профиль   Отправить e-mail  

выбор ip при использовании smtplib

caribbean_snow
В какую сторону копать? Альтернатив smtplib с нужным функционалом я не нашел.
Была аналогичная проблема - решил ее грязным хаком smtplib, сделав bind сокета на указанный интерфейс. Криво, конечно, но на большее не было времени :-)



Офлайн

#6 Окт. 22, 2009 15:07:05

caribbean_snow
От:
Зарегистрирован: 2009-10-21
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

выбор ip при использовании smtplib

Может кому нибудь пригодится решение
connect() выдран из 2.5, добавлено пару строчек

class BindableSMTP(smtplib.SMTP):
def __init__(self, host='', port=0, local_hostname=None, *args, **kwargs):
self.interface = kwargs.get('interface', None)
smtplib.SMTP.__init__(self, host, port, local_hostname)

def connect(self, host='localhost', port = 0):
if not port and (host.find(':') == host.rfind(':')):
i = host.rfind(':')
if i >= 0:
host, port = host[:i], host[i+1:]
try: port = int(port)
except ValueError:
raise socket.error, "nonnumeric port"
if not port: port = SMTP_PORT
if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
msg = "getaddrinfo returns an empty list"
self.sock = None
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
#added lines
if self.interface:
self.sock.bind((self.interface, 0))
if self.debuglevel > 0: print>>stderr, 'connect:', sa
self.sock.connect(sa)
except socket.error, msg:
if self.debuglevel > 0: print>>stderr, 'connect fail:', msg
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
(code, msg) = self.getreply()
if self.debuglevel > 0: print>>stderr, "connect:", msg
return (code, msg)
Юзать так
conn = BindableSMTP('smtp.server.com',587, interface='123.123.123.123')



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version