2

로컬 네트워크에서 열린 포트를 검색하고 연결된 소켓을 로컬 주소와 함께 사전에 저장하는 간단한 프로그램이 있습니다. 이제 Manager 공유 사전을 사용하여 이러한 항목을 저장하지만 소켓 인스턴스가 아닌 단순 개체 만 허용합니다.Python 2.7 다중 처리 - 관리자 사전을 통한 소켓 객체 통과 금지

from multiprocessing import Process, Manager 
import socket 

manager = Manager() 
# Store connected sockets 
sockets = manager.dict() 


def ping_addr(addr=None, port=None, timeout=None): 
    """ 
    Create a socket and try to establish a connection to a specific address. If a connection is established, append 
    the socket to the sockets dictionary. 
    :param addr: The address. 
    :param port: The port number. 
    :param timeout: How many seconds to wait until its decided that the connection has been refused. 
    :return: None 
    """ 
    global sockets 
    # Setup the client socket 
    csocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    csocket.settimeout(timeout) 
    # Try to connect 
    try: 
     csocket.connect((addr, port)) 
     print 'connected to {}:{}'.format(addr, port) 
     # This works 
     sockets.update({addr: 0}) 
     # This doesnt work 
     sockets.update({addr: csocket}) 
    except socket.error: 
     pass 


for i in range(256): 
    proc = Process(target=ping_addr, kwargs={'addr': '192.168.1.{}'.format(i), 'port': 14540, 'timeout': 0.5}) 
    proc.start() 

내가 오류는 다음과 같습니다 : 여기에 코드입니다

Process Process-4: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap 
    self.run() 
    File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run 
    self._target(*self._args, **self._kwargs) 
    File "/home/alex/PycharmProjects/proj/test.py", line 29, in ping_addr 
    sockets.update({addr: csocket}) 
    File "<string>", line 2, in update 
    File "/usr/lib/python2.7/multiprocessing/managers.py", line 758, in _callmethod 
    conn.send((self._id, methodname, args, kwds)) 
TypeError: expected string or Unicode object, NoneType found 

내가 프록시에 대한 간단한 조사를했지만 내 코드로 구현하는 방법을 찾을 수 없습니다, 그래서 내가 부탁하고 도와주기 위해. 소켓 사전을 Manager 사전과 호환되게하려면 어떻게해야합니까?

답변

2

자식 프로세스를 부모로부터 소켓을 통과하는 것은 매우 일반적입니다 참조하십시오. python3.4로 시작하는 (see full gist here)을, 당신은 multiprocessing.Manager를 통해 직접 소켓 객체를 공유 할 수 있지만, python2.7에서, 사용자가 스스로를 연결해야합니다 :

import socket 
import copy_reg 
from multiprocessing.reduction import rebuild_socket, reduce_socket 

copy_reg.pickle(socket.socket, reduce_socket, rebuild_socket) 
0

소켓을 Manager.dict를 통해 다른 프로세스로 전달할 수 없습니다. 각 파이썬 소켓은 OS 레벨에 소켓을 가지고 있습니다. OS는 소켓과 프로세스 사이의 바인딩을 알고 소켓 소유권을 유지합니다. 소켓은 소켓을 만든 프로세스에서만 사용할 수 있습니다. 또는 시스템과 같은 유닉스에서 자식 프로세스에 사용될 수도있다.

Passing Python object to another Python process

+0

는 "소켓이 다른 프로세스에 전달 될 수없는"상태 ,하지만 당신은 반대 의견을 제안 링크를 참조 ... – georgexsh