示例#1
0
 def start_work(self, conn: socket.socket, addr: Tuple[str, int]) -> None:
     if self.flags.threadless and \
             self.threadless_client_queue and \
             self.threadless_process:
         self.threadless_client_queue.send(addr)
         send_handle(
             self.threadless_client_queue,
             conn.fileno(),
             self.threadless_process.pid
         )
         conn.close()
     else:
         work = self.work_klass(
             TcpClientConnection(conn, addr),
             flags=self.flags,
             event_queue=self.event_queue
         )
         work_thread = threading.Thread(target=work.run)
         work_thread.daemon = True
         work.publish_event(
             event_name=eventNames.WORK_STARTED,
             event_payload={'fileno': conn.fileno(), 'addr': addr},
             publisher_id=self.__class__.__name__
         )
         work_thread.start()
示例#2
0
    def create_file_event(self, fd: socket.socket, mask: int, handler,
                          privdata):
        '''
        将给定fd的给定事件添加到events中
        添加到events的FileEvent结构由mask, handler, privdata共同决定
        如果已存在, 则更新FileEvent
        :param fd: 描述符(socket)
        :param mask: 表示读写的标志, 根据此更新FileEvent的可读写状态
        :param handler: 事件发生时的回调函数
        :param privdata: handler需要的数据, 保存在FileEvent中
        :return:
        '''
        # logging.info("new event, fd: {}, mask: {}".format(fd.fileno(), mask))
        fe = self.events.setdefault(fd.fileno(), FileEvent())
        self.event_add(fd, mask)

        fe.mask |= mask
        if mask & READABLE:
            fe.readhandler = handler
        if mask & WRITEABLE:
            fe.writehandler = handler
        fe.client = privdata
        fe.fd = fd

        if fd.fileno() > self.maxfd:
            self.maxfd = fd.fileno()
示例#3
0
def read(sock: socket.socket):
    f = Future()

    def on_readable():
        f.set_result(sock.recv(4096))

    selector.register(sock.fileno(), EVENT_READ, on_readable)
    chunk = yield f  # 读一个chunk
    selector.unregister(sock.fileno())
    return chunk
示例#4
0
async def read(sock: socket.socket) -> bytes:
    '''从 socket 中读取bytes
    '''
    f = Future()

    def on_readable():
        f.set_result(sock.recv(4096))

    selector.register(sock.fileno(), EVENT_READ, on_readable)
    chunck = await f
    # 移除监听
    selector.unregister(sock.fileno())
    return chunck
示例#5
0
def start_threaded_work(
    flags: argparse.Namespace,
    conn: socket.socket,
    addr: Optional[Tuple[str, int]],
    event_queue: Optional[EventQueue] = None,
    publisher_id: Optional[str] = None,
) -> Tuple['Work[T]', threading.Thread]:
    """Utility method to start a work in a new thread."""
    work = flags.work_klass(
        flags.work_klass.create(conn=conn, addr=addr),
        flags=flags,
        event_queue=event_queue,
        upstream_conn_pool=None,
    )
    # TODO: Keep reference to threads and join during shutdown.
    # This will ensure connections are not abruptly closed on shutdown
    # for threaded execution mode.
    thread = threading.Thread(target=work.run)
    thread.daemon = True
    thread.start()
    work.publish_event(
        event_name=eventNames.WORK_STARTED,
        event_payload={
            'fileno': conn.fileno(),
            'addr': addr
        },
        publisher_id=publisher_id or 'thread#{0}'.format(thread.ident, ),
    )
    return (work, thread)
示例#6
0
def client_handler(client: socket.socket):
    logic.menu(client)
    while True:
        msg = tcp_server.recv_msg(client)
        if client is None:
            return
        if msg is not None:
            msg = msg.split()

        # Validate Command
        if logic.validate_command(msg):
            tcp_server.send_msg(client, logic.error_msg_prefix + "Invalid command")
            continue
        # Validate Registry
        if logic.validate_registration(client, msg) and 'exit' not in msg:
            tcp_server.send_msg(client, logic.error_msg_prefix + "Please register first. \n")
            continue
        # Then execute game action

        try:
            threading.Thread(target=logic.commands_handler.get(msg[0].lower()), args=(client, msg,)).start()
        except:
            if client is None or client.fileno() == -1:
                break
            tcp_server.send_msg(client, "There was a problem procesing your request\n")
示例#7
0
def accept_handler(serversocket: socket.socket) -> None:
    clientsocket, (client_address, client_port) = serversocket.accept()
    clientsocket.setblocking(False)
    logging.debug(f"New client: {client_address}:{client_port}")
    connections[clientsocket.fileno()] = (clientsocket, client_address, client_port)
    read_waiters[clientsocket.fileno()] = (recv_handler, (clientsocket.fileno(),))
    read_waiters[serversocket.fileno()] = (accept_handler, (serversocket,))
    async def send(self, client_socket: socket):
        loop = asyncio.get_event_loop()

        raw_utf = f'{self._protocol} {self._status} {STATUS_MESSAGES[self._status]}\r\n' + \
                  '\r\n'.join([f'{key}: {value}' for key, value in self._headers.items()]) + '\r\n\r\n'
        raw_bytes = raw_utf.encode()

        await loop.sock_sendall(client_socket, raw_bytes)

        if self._filepath is not None and self._method == 'GET':
            with open(self._filepath, 'rb') as file:
                if Config.sendfile:
                    try:
                        await loop.run_in_executor(None, os.sendfile,
                                                   client_socket.fileno(),
                                                   file.fileno(), 0,
                                                   getsize(self._filepath))
                    except (BrokenPipeError, ConnectionResetError) as e:
                        logging.warning(e)
                        return
                else:
                    part = file.read(Config.bytes_per_send)
                    while len(part) > 0:
                        try:
                            await loop.sock_sendall(client_socket, part)
                        except (BrokenPipeError, ConnectionResetError) as e:
                            logging.warning(e)
                            return
                        part = file.read(Config.bytes_per_send)
示例#9
0
    def del_client(self, conn: socket.socket):
        addr = conn.getpeername()
        if addr not in self.clients.keys():
            raise ClientNotExistException()

        self.server.remove_handler(conn.fileno())
        del self.clients[addr]
示例#10
0
async def connect(sock: socket.socket, address: Tuple) -> None:
    f = Future()
    # 将socket 设置为非阻塞模式
    sock.setblocking(False)
    try:
        sock.connect(address)
    except BlockingIOError:
        pass

    def on_connected():
        f.set_result(None)

    selector.register(sock.fileno(), EVENT_WRITE, on_connected)
    await f
    # 移除监听
    selector.unregister(sock.fileno())
示例#11
0
def io_transfer(iosock: socket.socket, flag, ifreq):
    """
     send & recieve an ifreq struct
     :param iosock: io socket
     :param flag: sockios control call
     :param ifreq: ifreq to send
     :returns: an the ifreq struct recieved
    """
    try:
        return ioctl(iosock.fileno(), flag, ifreq)
    except (AttributeError, struct.error) as e:
        # either sock is not valid or a bad value passed to ifreq
        if e.message.find("fileno"):
            raise EnvironmentError(errno.ENOTSOCK, "Bad socket")
        else:
            raise EnvironmentError(errno.EINVAL, e)
    except IOError as e:
        # generally device cannot be found sort but can also be
        # permissions etc, catch and reraise as our own
        if e.errno is not None:  # just in case we have a none 2-tuple error
            raise EnvironmentError(e.errno, e.strerror)
        else:
            raise EnvironmentError(-1, "Undefined error")
    except Exception as e:
        # blanket catchall
        raise EnvironmentError(-1, e.args[0])
示例#12
0
 def unregister_sock(self, sock: socket) -> None:
     """
     Unregister the given sock with the polling object, and internal dict.
     """
     fileno = sock.fileno()
     self.poller.unregister(fileno)
     del self.socket_filenos[fileno]
示例#13
0
 def _work(self, conn: socket.socket, addr: Optional[Tuple[str,
                                                           int]]) -> None:
     self._total = self._total or 0
     if self.flags.threadless:
         # Index of worker to which this work should be dispatched
         # Use round-robin strategy by default.
         #
         # By default all acceptors will start sending work to
         # 1st workers.  To randomize, we offset index by idd.
         index = (self._total + self.idd) % self.flags.num_workers
         thread = threading.Thread(
             target=delegate_work_to_pool,
             args=(
                 self.executor_pids[index],
                 self.executor_queues[index],
                 self.executor_locks[index],
                 conn,
                 addr,
                 self.flags.unix_socket_path,
             ),
         )
         thread.start()
         # TODO: Move me into target method
         logger.debug(  # pragma: no cover
             'Dispatched work#{0}.{1}.{2} to worker#{3}'.format(
                 conn.fileno(),
                 self.idd,
                 self._total,
                 index,
             ), )
     else:
         _, thread = start_threaded_work(
             self.flags,
             conn,
             addr,
             event_queue=self.event_queue,
             publisher_id=self.__class__.__name__,
         )
         # TODO: Move me into target method
         logger.debug(  # pragma: no cover
             'Started work#{0}.{1}.{2} in thread#{3}'.format(
                 conn.fileno(),
                 self.idd,
                 self._total,
                 thread.ident,
             ), )
     self._total += 1
示例#14
0
 def __init__(self, sock: socket, loop: BaseLoop = None, app=None):
     self._socket = sock
     self.fd = sock.fileno()
     self.loop = loop
     self.app = app
     self.request: Request = None
     self.response: Response = None
     self._socket.setblocking(False)
示例#15
0
    def _on_socket_close(self, client: mqtt.Client, userdata: Any,
                         sock: socket.socket) -> None:

        fileno = sock.fileno()
        if fileno > -1:
            self._loop.remove_reader(fileno)
        if self._misc_task is not None and not self._misc_task.done():
            self._loop.call_soon_threadsafe(self._misc_task.cancel)
示例#16
0
async def connect(protocol_factory: Callable[..., ConnectionBase],
                  address: str = None,
                  port: int = None,
                  family=AF_INET,
                  type=SOCK_STREAM,
                  proto=0,
                  fileno=None,
                  bufsize: int = 1024,
                  sock: socket = None):
    if sock is not None:
        if fileno is not None:
            raise ValueError("You cannot specify a fileno AND a socket!")
        try:
            sock.getpeername()
            connected = False
        # We want to check if the sock is connected already
        except OSError:  # It'll raise an OSError if we try to getpeername of an unconnected sock
            if address is not None or port is not None:
                raise ValueError(
                    "You cannot specify both an address/port AND a connected socket!"
                ) from None
            connected = True
    else:
        sock = socket(family=family, type=type, proto=proto, fileno=fileno)
        connected = False

    connection = protocol_factory(
        socket=sock, host=(address, port),
        bufsize=bufsize)  # All protos need these args

    if not connected:
        await connection._connect(
        )  # If the sock isn't connected, connect "asynchronously"

    loop = await get_loop()
    if not isinstance(loop, IOCPLoop):
        await create_writer(sock, connection._writer_callback
                            )  # Create our reader and writer
    else:
        if sock.fileno() not in loop._open_ports:
            _overlapped.CreateIoCompletionPort(sock.fileno(), loop._port, 0, 0)
            loop._open_ports.append(sock.fileno())
    await create_reader(sock, connection._reader_callback)

    return connection
示例#17
0
    def __read_socket(self, s: socket.socket):
        """
        Handles sockets that has data to be read/incomming connections
        """
        if s is self.__socket:  # If socket is servers own socket, we have a new client connecting
            connection, addr = s.accept()  # Accept client
            connection.setblocking(0)  # Asynchronous input

            # Store info about client
            self.__sockets_read.append(connection)
            self.__response_queues[connection] = queue.Queue()
            self.on_client_connected(addr)

        else:  # A clients socket has data to be read
            header = self.__header_buffer.get(
                s.getpeername(), None
            )  # Has this client sent data before? Get the previous data (header) sent
            n = header.size if header is not None else PacketHeader.SIZE  # Get the expected size to read (as stated in the header) or (if the header doesnt exist, which means this is the first data from that client to be received) set the size to header size

            avail = self._available_bytes(
                s.fileno())  # Get size of the data awaiting to be read
            if avail < n:  # Available data size is not (yet) sufficient
                if avail <= 0:  # If we have data request with no size, the client has disconnected
                    self.on_client_disconnected(s.getpeername())
                    self.__close_socket(s)

                return  # If size of the data is less than expected, wait for more in the next call

            data = s.recv(n) if n > 0 else None  # Receive the acctual data
            if header is None:  # If we don't have previous data form this client
                if data is None:  # This is not expected
                    return

                header = PacketHeader._make(
                    struct.unpack(PacketHeader.FORMAT,
                                  data))  # Unpack header data
                self.__header_buffer[s.getpeername(
                )] = header  # Associente this header to client
                if header.size > 0:  # If expecting more data receive it in the next call
                    return

            # Here we are guaranteed to have a header, but not necessarily any data after that (i.e: header != None and (data == None or data != None))
            if self.on_data_received(header, data):  # Call callback
                response = struct.pack(PacketHeader.FORMAT, int(PacketID.TRUE),
                                       0)  # Success packet to be sent back
            else:
                response = struct.pack(PacketHeader.FORMAT,
                                       int(PacketID.FALSE),
                                       0)  # Fail packet to be sent back

            self.__response_queues[s].put(response)  # Queue response packet
            if s not in self.__sockets_write:
                self.__sockets_write.append(
                    s)  # Append cliet socket to write queue

            del self.__header_buffer[s.getpeername(
            )]  # Remove associated header from client as it's already processed
示例#18
0
def hci_le_set_scan_enable(sock: socket.socket, enable: bool,
                           filter_duplicates: bool, timeout: int) -> None:
    """
    Enable or disable LE scanning.
    """
    err = BLUEZ.hci_le_set_scan_enable(sock.fileno(), enable,
                                       filter_duplicates, timeout)
    if err < 0:
        raise BluezError("hci_le_set_scan_enable")
示例#19
0
    def add_client(self, conn: socket.socket):
        addr = conn.getpeername()
        if addr in self.clients.keys():
            raise ClientExistException()

        client = Client(self, conn)

        self.server.add_handler(conn.fileno(), client.recv, EVENT_READ)
        self.clients[addr] = client
示例#20
0
    def __init__(self,
                 loop: asyncio.BaseEventLoop,
                 rawsock: socket.socket,
                 protocol: asyncio.Protocol,
                 ssl_context_factory: SSLContextFactory,
                 waiter: typing.Optional[asyncio.Future] = None,
                 use_starttls: bool = False,
                 post_handshake_callback: typing.
                 Optional[PostHandshakeCallback] = None,
                 peer_hostname: typing.Optional[str] = None,
                 server_hostname: typing.Optional[str] = None):
        if not use_starttls and not ssl_context_factory:
            raise ValueError("Cannot have STARTTLS disabled (i.e. immediate "
                             "TLS connection) and without SSL context.")

        super().__init__()
        self._rawsock = rawsock
        self._raw_fd = rawsock.fileno()
        self._trace_logger = logger.getChild("trace.fd={}".format(
            self._raw_fd))
        self._sock = rawsock  # type: typing.Union[socket.socket, OpenSSL.SSL.Connection]  # noqa
        self._send_wrap = SendWrap(self._sock)
        self._protocol = protocol
        self._loop = loop
        self._extra = {
            "socket": rawsock,
        }  # type: typing.Dict[str, typing.Any]
        self._waiter = waiter
        self._conn_lost = 0
        self._buffer = bytearray()
        self._ssl_context_factory = ssl_context_factory
        self._extra.update(sslcontext=None,
                           ssl_object=None,
                           peername=self._rawsock.getpeername(),
                           peer_hostname=peer_hostname,
                           server_hostname=server_hostname)

        # this is a list set of tasks which will also be cancelled if the
        # _waiter is cancelled
        self._chained_pending = set()  # type: typing.Set[asyncio.Future]

        self._paused = False
        self._closing = False

        self._tls_conn = None  # type: typing.Optional[OpenSSL.SSL.Connection]
        self._tls_read_wants_write = False
        self._tls_write_wants_read = False
        self._tls_post_handshake_callback = post_handshake_callback

        self._state = None  # type: typing.Optional[_State]
        if not use_starttls:
            self._ssl_context = ssl_context_factory(self)
            self._extra.update(sslcontext=self._ssl_context, )
            self._initiate_tls()
        else:
            self._initiate_raw()
示例#21
0
def _netmask_for_ifacename(name: str, sock: socket.socket) -> Optional[str]:
    siocgifnetmask = 0x891b
    bytebuf = struct.pack('256s', name.encode('utf-8'))
    try:
        ret = fcntl.ioctl(sock.fileno(), siocgifnetmask, bytebuf)
    except OSError:
        logging.error('siocgifnetmask failed')
        return None

    return socket.inet_ntoa(ret[20:24])
    def __init__(self, clientsocket: socket.socket):
        super().__init__(fileno=clientsocket.fileno())

        self.session_count = ClientSession.session_count + 1
        ClientSession.session_count += 1

        self.write_buffer = bytearray()
        self.read_buffer = bytearray()

        logging.info(
            f"{self.getpeername()} connected as client #{self.session_count}")
示例#23
0
    def create_client(self, sock: socket.socket):
        if self.client_exists(sock):
            return

        client = Client(sock)

        self.clients[sock.fileno()] = client
        self.sockets[sock.fileno()] = sock
        self.poller.register(sock, select.POLLIN)

        print(str(client), "connected.")
示例#24
0
文件: server.py 项目: zuzhi/rssant
 def handler(self, cli_sock: socket.socket, cli_addr):
     client_name = 'fd={}'.format(cli_sock.fileno())
     LOG.info(f'client {client_name} enter backdoor!')
     handler = BackdoorHandler(self, cli_sock, cli_addr)
     _BACKDOOR_HANDLER.handler = handler
     try:
         handler.handle()
     finally:
         LOG.info(f'client {client_name} exit backdoor!')
         handler.close()
         _BACKDOOR_HANDLER.handler = None
def _launch_repo_server(
    *,
    repo_server_bin: Path,
    sock: socket.socket,
    snapshot_dir: Path,
    debug: bool,
):
    '''
    Invokes `repo-server` with the given snapshot; passes it ownership of
    the bound TCP socket -- it listens & accepts connections.
    '''
    # This could be a thread, but it's probably not worth the risks
    # involved in mixing threads & subprocess (yes, lots of programs do,
    # but yes, far fewer do it safely).
    with sock, subprocess.Popen([
        repo_server_bin,
        '--socket-fd', str(sock.fileno()),
        '--snapshot-dir', snapshot_dir,
        *(['--debug'] if debug else []),
    ], pass_fds=[sock.fileno()]) as server_proc:
        try:
            log.info('Waiting for repo server to listen')
            while server_proc.poll() is None:
                if sock.getsockopt(socket.SOL_SOCKET, socket.SO_ACCEPTCONN):
                    break
                time.sleep(0.1)
            yield
        finally:
            # Although `repo-server` is a read-only proxy, give it the
            # chance to do graceful cleanup.
            log.info('Trying to gracefully terminate `repo-server`')
            # `atexit` (used in an FB-specific `repo-server` plugin) only
            # works with SIGINT.  We signal once, and need to wait for it to
            # clean up the resources it must to free.  Signaling twice would
            # interrupt cleanup (because this is Python, lol).
            server_proc.send_signal(signal.SIGINT)  # `atexit` needs this
            try:
                server_proc.wait(60.0)
            except subprocess.TimeoutExpired:  # pragma: no cover
                log.info('Killing unresponsive `repo-server`')
                server_proc.kill()
示例#26
0
文件: web.py 项目: shuxiang/eurasia
	def __init__(self):
		global server_socket, serverpid
		server_socket = Socket(AF_INET, SOCK_STREAM)
		server_socket.setblocking(0)
		try:
			server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,
				server_socket.getsockopt(SOL_SOCKET, SO_REUSEADDR) | 1)
		except error:
			pass

		serverpid = server_socket.fileno()
		pollster.register(serverpid, RE)
示例#27
0
def _repo_server(sock: socket.socket, storage_cfg: str, snapshot_dir: Path):
    '''
    Invokes `repo-server` with the given storage & snapshot; passes it
    ownership of the bound TCP socket -- it listens & accepts connections.
    '''
    # This could be a thread, but it's probably not worth the risks
    # involved in mixing threads & subprocess (yes, lots of programs do,
    # but yes, far fewer do it safely).
    with sock, subprocess.Popen([
            os.path.join(os.path.dirname(__file__), 'repo-server'),
            '--socket-fd',
            str(sock.fileno()),
            '--storage',
            storage_cfg,
            '--snapshot-dir',
            snapshot_dir,
    ],
                                pass_fds=[sock.fileno()]) as server_proc:
        try:
            yield server_proc
        finally:
            server_proc.kill()  # It's a read-only proxy, abort ASAP
示例#28
0
 def read(conn: socket.socket, mask: int):
     with conn:
         s_file = fdopen(conn.fileno(),
                         "rb",
                         buffering=0)
         try:
             obj = pickle.Unpickler(s_file).load()
             # False obj means skip
             if obj:
                 self.tool_calls.append(obj)
                 formatted_out(f_out, obj)
         finally:
             sel.unregister(conn)
示例#29
0
    async def send(self, sock: socket.socket):
        await asyncio.get_event_loop().sock_sendall(sock, self.head_to_string().encode(C.ENCODING))

        # send body
        if self.status == C.HTTP_STATUS_CODE_OK and self.path and self.method == C.METHOD_GET:
            with open(self.path, 'rb') as file:
                # Using lib sendfile
                offset = 0
                blocksize = os.path.getsize(self.path)
                while True:
                    sent = sendfile.sendfile(sock.fileno(), file.fileno(), offset, blocksize)
                    offset += sent
                    if sent == 0:
                        break
示例#30
0
def hci_le_set_scan_parameters(sock: socket.socket, scan_type: ScanType,
                               scan_interval: int, scan_window: int,
                               address_type: AddressType,
                               filter_policy: FilterPolicy,
                               timeout: int) -> None:
    """
    Set LE scanning parameters.
    """
    err = BLUEZ.hci_le_set_scan_parameters(sock.fileno(), scan_type.value,
                                           scan_interval, scan_window,
                                           address_type.value,
                                           filter_policy.value, timeout)
    if err < 0:
        raise BluezError("hci_le_set_scan_parameters")
示例#31
0
文件: tcp.py 项目: mnot/thor
    def __init__(self, sock: socket.socket, host: bytes, port: int, loop: LoopBase = None) -> None:
        EventSource.__init__(self, loop)
        self.socket = sock
        self.host = host
        self.port = port
        self.tcp_connected = True  # we assume a connected socket
        self._input_paused = True  # we start with input paused
        self._output_paused = False
        self._closing = False
        self._write_buffer = []  # type: list[bytes]

        self.register_fd(sock.fileno())
        self.on("fd_readable", self.handle_readable)
        self.on("fd_writable", self.handle_writable)
        self.on("fd_close", self._handle_close)
示例#32
0
文件: IRCBot.py 项目: jesopo/bitbot
 def add_socket(self, sock: socket.socket):
     self.other_sockets[sock.fileno()] = sock
     self.poll.register(sock.fileno(), select.EPOLLIN)
示例#33
0
文件: IRCBot.py 项目: jesopo/bitbot
 def remove_socket(self, sock: socket.socket):
     del self.other_sockets[sock.fileno()]
     self.poll.unregister(sock.fileno())