4 Module for receiving AIVDM data from outbound TCP connection.
7 from __future__ import division
11 from ais.inputs.common import DEFAULT_MTU, get_source_by_id4
12 from ais.inputs.virtual import Channel, ServiceIn
16 class TcpOutChannel(Channel):
18 Channel bound to a TCP server and listen for data there.
20 def __init__(self, id4, hostname, port):
21 Channel.__init__(self)
23 self.source = get_source_by_id4(id4)
24 self.hostname = hostname
26 self.name = '%s:%s' % (self.hostname, self.port)
27 address_out = (self.hostname, self.port)
29 # TODO try all IP addresses
30 # see http://docs.python.org/library/socket.html#example
32 self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
33 self.sock.connect(address_out)
34 logging.info("Connected to %s using tcp6", address_out)
35 except socket.gaierror as err:
36 logging.error("Can't connet to %s: %s using tcp6", address_out, err)
37 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
39 self.sock.connect(address_out)
40 except socket.error as err:
41 logging.error("Can't connet to %s: %s using tcp4", address_out, err)
43 logging.info("Connected to %s using tcp4", address_out)
45 def fill_buffer(self):
47 Grab more bytes into self.data internal buffer.
49 data = self.sock.recv(DEFAULT_MTU)
52 assert data, 'Connection closed'
53 stats = self.source.stats
55 stats.nbytes += len(data)
56 stats.nbytes_ethernet += len(data) + TCP_HEADER_SIZE
57 logging.debug('IN %s %s', self.name, repr(data))
61 class TcpOutServiceIn(ServiceIn):
63 Service that connects to a TCP server and listen for data there.
65 def __init__(self, id4, hostname, port):
66 #ServiceIn.__init__(self, stdout)
67 self.channel = TcpOutChannel(id4, hostname, port)
70 return 'TcpOutServiceIn<%s,%s>' \
71 % (self.channel.hostname, self.channel.port)
75 Returns file descriptor of underlying socket, for os.select().
77 return self.channel.sock.fileno()
79 def get_activity(self):
81 Pool the channel and returns information when ready.
83 channel = self.channel
85 return channel.name, channel