Отказ в соединении при попытке открыть, написать и закрыть сокет несколько раз (Python) - PullRequest
2 голосов
/ 18 июля 2009

У меня есть программа, которая прослушивает порт в ожидании небольшого количества данных, чтобы сообщить ему, что делать. Я запускаю 5 экземпляров этой программы, по одному на каждый порт от 5000 до 5004 включительно.

У меня есть вторая программа, написанная на Python, которая создает сокет "s", записывает данные в порт 5000, а затем закрывается. Затем он увеличивает номер порта и создает новый сокет, подключенный к 5001. Он делает это, пока не достигнет 5004.

Первые три сокетных соединения работают просто отлично. Программы на портах с 5000 по 5002 получают данные очень хорошо и они уходят! Однако подключение четвертого сокета приводит к сообщению об ошибке «Соединение отказано». Между тем, четвертая программа прослушивания все еще сообщает, что ожидает на порту 5003. Я знаю, что она прослушивает правильно, потому что я могу подключиться к ней через Telnet.

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

Есть ли какие-то ограничения в системе, которые я должен проверить? У меня только одна розетка открыта в любое время на стороне отправителя, и тот факт, что я могу получить 3 из 5, устраняет многие основные шаги по устранению неполадок, о которых я могу думать.

Есть мысли? Спасибо!

--- РЕДАКТИРОВАТЬ ---

Я работаю в CentOS Linux с Python версии 2.6. Вот пример кода:

try:
        portno = 5000
        for index, data in enumerate(data_list):
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect(('myhostname', portno))
                s.sendall(data)
                s.close()
                portno = portno + 1
except socket.error, (value,message):
        print 'Error: Send could not be performed.\nPort: ' + str(portno) + '\nMessage: ' + message
        sys.exit(2)

Ответы [ 3 ]

1 голос
/ 18 июля 2009

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

#!/usr/bin/python
import threading, time
from socket import *
portrange = range(10000,10005)

class Sock(threading.Thread):
    def __init__(self, port):
        self.port = port
        threading.Thread.__init__ ( self )

    def start(self):
        self.s = socket(AF_INET, SOCK_STREAM)
        self.s.bind(("localhost", self.port))
        self.s.listen(1)
        print "listening on port %i"%self.port
        threading.Thread.start(self)
    def run(self):
        # wait for client to connect
        connection, address = self.s.accept()
        data = True
        while data:
            data = connection.recv(1024)
            if data:
                connection.send('echo %s'%(data))
        connection.close()

socketHandles = [Sock(port) for port in portrange]

for sock in socketHandles:
    sock.start()

# time.sleep(0.5)

for port in portrange:
    print 'sending "ping" to port %i'%port
    s = socket(AF_INET, SOCK_STREAM) 
    s.connect(("localhost", port))
    s.send('ping')
    data = s.recv(1024)
    print 'reply was: %s'%data
    s.close()

должно вывести:

listening on port 10000
listening on port 10001
listening on port 10002
listening on port 10003
listening on port 10004
sending "ping" to port 10000
reply was: echo ping
sending "ping" to port 10001
reply was: echo ping
sending "ping" to port 10002
reply was: echo ping
sending "ping" to port 10003
reply was: echo ping
sending "ping" to port 10004
reply was: echo ping

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

1 голос
/ 18 июля 2009

Это звучит так же, как мера антипорт-сканирования вашего брандмауэра

0 голосов
/ 18 июля 2009

Запускаете ли вы вторую программу Python из Idle? Если это так - попробуйте это за пределами Idle и посмотрите, если результаты отличаются.

...