aboutsummaryrefslogtreecommitdiff
path: root/socket_conn.py
blob: 6906c0be8f962e48f4c90ee0d2e6fb352b869e12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#
# Describe a connection over a socket.
#
# This class is intended to be apdapted into IEndpoint interface

import socket
from zope import interface
import errno
import select

from interfaces import endpoint

from zope import component
from interfaces.message import Debug

@interface.implementer(endpoint.IConnection)
class SocketConnection(object):
    """ Define a connected element (serial, network…)
    """

    def __init__(self, configuration):
        self.port = int(configuration["port"])
        self.host = configuration["host"]

    def connect(self) -> None:
        """ Connect """
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((self.host, self.port))
        component.handle(Debug("Connected to the socket"))

    def read(self) -> str:
        """ Read from the connection and return the bytes.
            Return None if there is nothing to read (non-blocking)
            Raise an exception if disconnected """
        # check the socket for reading in non-blocking mode
        read_socket, _, _ = select.select([self.s], [], [], 0.0)
        if read_socket == []: return
        try:
            recv = self.s.recv(1024)
            if recv == b"":
                # We should be able to read something, but got nothing.
                # Reset the socket
                raise RuntimeError("socket connection broken")
            return recv
        except socket.error as e:
            err = e.args[0]
            if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
                return None
            raise e

    def write(self, content:str) -> None:
        """ Write into the connection.
            Raise an exception if disconnected """
        self.s.sendall(content + bytes("\n", "utf-8"))