cengal.io.asock_io.versions.v_0.tcp_link

Module Docstring Docstrings: http://www.python.org/dev/peps/pep-0257/

  1#!/usr/bin/env python
  2# coding=utf-8
  3
  4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>
  5# 
  6# Licensed under the Apache License, Version 2.0 (the "License");
  7# you may not use this file except in compliance with the License.
  8# You may obtain a copy of the License at
  9# 
 10#     http://www.apache.org/licenses/LICENSE-2.0
 11# 
 12# Unless required by applicable law or agreed to in writing, software
 13# distributed under the License is distributed on an "AS IS" BASIS,
 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15# See the License for the specific language governing permissions and
 16# limitations under the License.
 17
 18
 19"""
 20Module Docstring
 21Docstrings: http://www.python.org/dev/peps/pep-0257/
 22"""
 23
 24
 25__author__ = "ButenkoMS <gtalk@butenkoms.space>"
 26__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>"
 27__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ]
 28__license__ = "Apache License, Version 2.0"
 29__version__ = "4.4.1"
 30__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>"
 31__email__ = "gtalk@butenkoms.space"
 32# __status__ = "Prototype"
 33__status__ = "Development"
 34# __status__ = "Production"
 35
 36
 37import socket
 38from contextlib import contextmanager
 39from cengal.base.classes import BaseClassSettings
 40from .base import *
 41
 42
 43
 44
 45__author__ = 'ButenkoMS <gtalk@butenkoms.space>'
 46
 47
 48class SimpleTcpLinkError(SimpleNetworkError):
 49    pass
 50
 51
 52class SimpleTcpLink:
 53    '''
 54    1 to 1 TCP connection.
 55    '''
 56    def __init__(self, settings: ConnectionSettings):
 57        '''
 58        Port should not be open to a external world!
 59        :param settings: ConnectionSettings()
 60        :return:
 61        '''
 62        self.settings = settings
 63        self.settings.check()
 64        self._block_state = True
 65        self._gate = None
 66        self._conn = None
 67        self._addr = None
 68
 69        self.message_size_len = MESSAGE_SIZE_LEN
 70        self.server_answer__keyword_accepted = SERVER_ANSWER__KEYWORD_ACCEPTED
 71        self.use_nodelay_inet = False
 72        pass
 73
 74    def connect(self):
 75        if ConnectionDirectionRole.server == self.settings.direction_role:
 76            self._gate = socket.socket(self.settings.socket_family, self.settings.socket_type,
 77                                       self.settings.socket_protocol, self.settings.socket_fileno)
 78            self._gate.bind(self.settings.socket_address)
 79            self._gate.listen(1)
 80            self._conn, self._addr = self._gate.accept()
 81            print('Connected by', self._addr)
 82            keyword_length_raw = self._conn.recv(self.message_size_len)
 83            keyword_length = int.from_bytes(keyword_length_raw, 'little')
 84            keyword = self._conn.recv(keyword_length)
 85            if keyword == self.settings.keyword:
 86                self._conn.sendall(self._pack_message(self.server_answer__keyword_accepted))
 87            else:
 88                # if we'll use loop, hang will be possible.
 89                raise SimpleTcpLinkError('Wrong keyword: {}. Should be: {}.'.format(
 90                    keyword, self.settings.keyword))
 91        elif ConnectionDirectionRole.client == self.settings.direction_role:
 92            self._conn = socket.socket(self.settings.socket_family, self.settings.socket_type,
 93                                       self.settings.socket_protocol, self.settings.socket_fileno)
 94            self._conn.connect(self.settings.socket_address)
 95            self.send_message_b(self.settings.keyword)
 96            if self.read_message_b() != self.server_answer__keyword_accepted:
 97                raise SimpleTcpLinkError('Server rejected the keyword: {}.'.format(
 98                    self.settings.keyword))
 99        else:
100            raise NotImplementedError('Unknown ConnectionDirectionRole.')
101
102        if self.use_nodelay_inet and (self._conn.family in INET_TYPE_CONNECTIONS):
103            self._conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
104
105    def send_message_b(self, data):
106        self._conn.sendall(len(data).to_bytes(self.message_size_len, 'little') + data)
107
108    def read_message_b(self):
109        return self._conn.recv(int.from_bytes(self._conn.recv(self.message_size_len), 'little'))
110
111    def send_message(self, data):
112        if self._block_state:
113            self.send_message_b(data)
114        else:
115            pass
116        pass
117
118    def read_message(self):
119        if self._block_state:
120            return self.read_message_b()
121        else:
122            pass
123
124    def message_io_iteration(self):
125        pass
126
127    def set_blocking(self, set_blocking_mode=True):
128        pass
129
130    def close(self):
131        if self._conn is not None:
132            self._conn.close()
133        if self._gate is not None:
134            self._gate.close()
135
136    def _pack_message(self, data):
137        return len(data).to_bytes(self.message_size_len, 'little') + data
138
139
140@contextmanager
141def simple_tcp_link_connect(simple_tcp_obj):
142    try:
143        simple_tcp_obj.connect()
144        yield simple_tcp_obj
145    except:
146        raise
147    finally:
148        simple_tcp_obj.close()
class SimpleTcpLinkError(cengal.io.asock_io.versions.v_0.base.SimpleNetworkError):
49class SimpleTcpLinkError(SimpleNetworkError):
50    pass

Common base class for all non-exit exceptions.

Inherited Members
builtins.Exception
Exception
builtins.BaseException
with_traceback
args