소켓을 여러 번 열고 쓰고 닫으려고 하면 연결이 거부되었습니다(Python).
문제
수행할 작업을 알려주기 위해 소량의 데이터를 기다리는 포트에서 수신 대기하는 프로그램이 있습니다.저는 5000에서 5004까지의 각 포트에서 하나씩 해당 프로그램의 5개 인스턴스를 실행합니다.
소켓 "s"를 생성하고 포트 5000에 데이터를 쓴 다음 닫히는 Python으로 작성된 두 번째 프로그램이 있습니다.그런 다음 포트 번호를 증가시키고 5001에 연결된 새 소켓을 만듭니다.5004에 도달할 때까지 이 작업을 수행합니다.
처음 세 개의 소켓 연결은 정상적으로 작동합니다.포트 5000~5002의 프로그램은 데이터를 정상적으로 수신하고 종료됩니다!그러나 네 번째 소켓 연결에서는 "Connection Refused" 오류 메시지가 나타납니다.그 사이에 네 번째 청취 프로그램은 여전히 포트 5003에서 대기 중이라고 보고합니다. Telnet을 사용하여 연결할 수 있기 때문에 제대로 청취하고 있다는 것을 알 수 있습니다.
포트 번호를 변경해 보았는데 매번 네 번째 연결이 실패했습니다.
시스템에 확인해야 할 제한 사항이 있나요?보내는 쪽에서는 언제든지 하나의 소켓만 열려 있고 5개 중 3개를 얻을 수 있다는 사실로 인해 제가 생각할 수 있는 기본 문제 해결 단계가 많이 필요하지 않습니다.
이견있는 사람?감사해요!
--- 편집하다 ---
저는 Python 버전 2.6이 설치된 CentOS Linux를 사용하고 있습니다.다음은 몇 가지 예제 코드입니다.
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)
해결책
이는 방화벽이 시작되는 안티 포트스캔 조치와 매우 흡사합니다.
다른 팁
제가 소켓에 대해 잘 알지 못해서 이건 정말 나쁜 스타일일 수도 있겠네요...자신의 책임하에 사용하십시오.이 코드는:
#!/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
아마도 이것은 방화벽이 문제를 일으키는지 확인하는 데 도움이 될 것입니다.나는 이것을 클라이언트와 서버로 분할해 볼 수도 있다고 생각합니다.
Idle 내에서 두 번째 Python 프로그램을 실행하고 있습니까?그렇다면 Idle 외부에서 시도해 보고 결과가 다른지 확인하세요.