cengal.io.asock_io.versions.v_1.tcp_link
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 18import socket 19from contextlib import contextmanager 20from cengal.base.classes import BaseClassSettings 21from .base import * 22 23""" 24Module Docstring 25Docstrings: http://www.python.org/dev/peps/pep-0257/ 26""" 27 28__author__ = "ButenkoMS <gtalk@butenkoms.space>" 29__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 30__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 31__license__ = "Apache License, Version 2.0" 32__version__ = "4.4.1" 33__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 34__email__ = "gtalk@butenkoms.space" 35# __status__ = "Prototype" 36__status__ = "Development" 37# __status__ = "Production" 38 39 40class SimpleTcpLinkError(SimpleNetworkError): 41 pass 42 43 44class SimpleTcpLink: 45 """ 46 1 to 1 TCP connection. 47 """ 48 def __init__(self, settings: ConnectionSettings): 49 """ 50 Port should not be open to a external world! 51 :param settings: ConnectionSettings() 52 :return: 53 """ 54 self.settings = settings 55 self.settings.check() 56 self._block_state = True 57 self._gate = None 58 self._conn = None 59 self._addr = None 60 61 self.message_size_len = MESSAGE_SIZE_LEN 62 self.server_answer__keyword_accepted = SERVER_ANSWER__KEYWORD_ACCEPTED 63 self.use_nodelay_inet = False 64 pass 65 66 def connect(self): 67 if ConnectionType.passive == self.settings.connection_type: 68 self._gate = socket.socket(self.settings.socket_family, self.settings.socket_type, 69 self.settings.socket_protocol, self.settings.socket_fileno) 70 self._gate.bind(self.settings.socket_address) 71 self._gate.listen(1) 72 self._conn, self._addr = self._gate.accept() 73 print('Connected by', self._addr) 74 keyword_length_raw = self._conn.recv(self.message_size_len) 75 keyword_length = int.from_bytes(keyword_length_raw, 'little') 76 keyword = self._conn.recv(keyword_length) 77 if keyword == self.settings.keyword: 78 self._conn.sendall(self._pack_message(self.server_answer__keyword_accepted)) 79 else: 80 # if we'll use loop, hang will be possible. 81 raise SimpleTcpLinkError('Wrong keyword: {}. Should be: {}.'.format( 82 keyword, self.settings.keyword)) 83 elif ConnectionType.active_connected == self.settings.connection_type: 84 self._conn = socket.socket(self.settings.socket_family, self.settings.socket_type, 85 self.settings.socket_protocol, self.settings.socket_fileno) 86 self._conn.connect(self.settings.socket_address) 87 self.send_message_b(self.settings.keyword) 88 if self.read_message_b() != self.server_answer__keyword_accepted: 89 raise SimpleTcpLinkError('Server rejected the keyword: {}.'.format( 90 self.settings.keyword)) 91 else: 92 raise NotImplementedError('Unknown ConnectionType.') 93 94 if self.use_nodelay_inet and (self._conn.family in INET_TYPE_CONNECTIONS): 95 self._conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 96 97 def send_message_b(self, data): 98 self._conn.sendall(len(data).to_bytes(self.message_size_len, 'little') + data) 99 100 def read_message_b(self): 101 return self._conn.recv(int.from_bytes(self._conn.recv(self.message_size_len), 'little')) 102 103 def send_message(self, data): 104 if self._block_state: 105 self.send_message_b(data) 106 else: 107 pass 108 pass 109 110 def read_message(self): 111 if self._block_state: 112 return self.read_message_b() 113 else: 114 pass 115 116 def message_io_iteration(self): 117 pass 118 119 def set_blocking(self, set_blocking_mode=True): 120 pass 121 122 def close(self): 123 if self._conn is not None: 124 self._conn.close() 125 if self._gate is not None: 126 self._gate.close() 127 128 def _pack_message(self, data): 129 return len(data).to_bytes(self.message_size_len, 'little') + data 130 131 132@contextmanager 133def simple_tcp_link_connect(simple_tcp_obj): 134 try: 135 simple_tcp_obj.connect() 136 yield simple_tcp_obj 137 except: 138 raise 139 finally: 140 simple_tcp_obj.close()
class
SimpleTcpLinkError(cengal.io.asock_io.versions.v_1.base.SimpleNetworkError):
Common base class for all non-exit exceptions.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- args
class
SimpleTcpLink:
45class SimpleTcpLink: 46 """ 47 1 to 1 TCP connection. 48 """ 49 def __init__(self, settings: ConnectionSettings): 50 """ 51 Port should not be open to a external world! 52 :param settings: ConnectionSettings() 53 :return: 54 """ 55 self.settings = settings 56 self.settings.check() 57 self._block_state = True 58 self._gate = None 59 self._conn = None 60 self._addr = None 61 62 self.message_size_len = MESSAGE_SIZE_LEN 63 self.server_answer__keyword_accepted = SERVER_ANSWER__KEYWORD_ACCEPTED 64 self.use_nodelay_inet = False 65 pass 66 67 def connect(self): 68 if ConnectionType.passive == self.settings.connection_type: 69 self._gate = socket.socket(self.settings.socket_family, self.settings.socket_type, 70 self.settings.socket_protocol, self.settings.socket_fileno) 71 self._gate.bind(self.settings.socket_address) 72 self._gate.listen(1) 73 self._conn, self._addr = self._gate.accept() 74 print('Connected by', self._addr) 75 keyword_length_raw = self._conn.recv(self.message_size_len) 76 keyword_length = int.from_bytes(keyword_length_raw, 'little') 77 keyword = self._conn.recv(keyword_length) 78 if keyword == self.settings.keyword: 79 self._conn.sendall(self._pack_message(self.server_answer__keyword_accepted)) 80 else: 81 # if we'll use loop, hang will be possible. 82 raise SimpleTcpLinkError('Wrong keyword: {}. Should be: {}.'.format( 83 keyword, self.settings.keyword)) 84 elif ConnectionType.active_connected == self.settings.connection_type: 85 self._conn = socket.socket(self.settings.socket_family, self.settings.socket_type, 86 self.settings.socket_protocol, self.settings.socket_fileno) 87 self._conn.connect(self.settings.socket_address) 88 self.send_message_b(self.settings.keyword) 89 if self.read_message_b() != self.server_answer__keyword_accepted: 90 raise SimpleTcpLinkError('Server rejected the keyword: {}.'.format( 91 self.settings.keyword)) 92 else: 93 raise NotImplementedError('Unknown ConnectionType.') 94 95 if self.use_nodelay_inet and (self._conn.family in INET_TYPE_CONNECTIONS): 96 self._conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 97 98 def send_message_b(self, data): 99 self._conn.sendall(len(data).to_bytes(self.message_size_len, 'little') + data) 100 101 def read_message_b(self): 102 return self._conn.recv(int.from_bytes(self._conn.recv(self.message_size_len), 'little')) 103 104 def send_message(self, data): 105 if self._block_state: 106 self.send_message_b(data) 107 else: 108 pass 109 pass 110 111 def read_message(self): 112 if self._block_state: 113 return self.read_message_b() 114 else: 115 pass 116 117 def message_io_iteration(self): 118 pass 119 120 def set_blocking(self, set_blocking_mode=True): 121 pass 122 123 def close(self): 124 if self._conn is not None: 125 self._conn.close() 126 if self._gate is not None: 127 self._gate.close() 128 129 def _pack_message(self, data): 130 return len(data).to_bytes(self.message_size_len, 'little') + data
1 to 1 TCP connection.
SimpleTcpLink(settings: cengal.io.asock_io.versions.v_1.base.ConnectionSettings)
49 def __init__(self, settings: ConnectionSettings): 50 """ 51 Port should not be open to a external world! 52 :param settings: ConnectionSettings() 53 :return: 54 """ 55 self.settings = settings 56 self.settings.check() 57 self._block_state = True 58 self._gate = None 59 self._conn = None 60 self._addr = None 61 62 self.message_size_len = MESSAGE_SIZE_LEN 63 self.server_answer__keyword_accepted = SERVER_ANSWER__KEYWORD_ACCEPTED 64 self.use_nodelay_inet = False 65 pass
Port should not be open to a external world! :param settings: ConnectionSettings() :return:
def
connect(self):
67 def connect(self): 68 if ConnectionType.passive == self.settings.connection_type: 69 self._gate = socket.socket(self.settings.socket_family, self.settings.socket_type, 70 self.settings.socket_protocol, self.settings.socket_fileno) 71 self._gate.bind(self.settings.socket_address) 72 self._gate.listen(1) 73 self._conn, self._addr = self._gate.accept() 74 print('Connected by', self._addr) 75 keyword_length_raw = self._conn.recv(self.message_size_len) 76 keyword_length = int.from_bytes(keyword_length_raw, 'little') 77 keyword = self._conn.recv(keyword_length) 78 if keyword == self.settings.keyword: 79 self._conn.sendall(self._pack_message(self.server_answer__keyword_accepted)) 80 else: 81 # if we'll use loop, hang will be possible. 82 raise SimpleTcpLinkError('Wrong keyword: {}. Should be: {}.'.format( 83 keyword, self.settings.keyword)) 84 elif ConnectionType.active_connected == self.settings.connection_type: 85 self._conn = socket.socket(self.settings.socket_family, self.settings.socket_type, 86 self.settings.socket_protocol, self.settings.socket_fileno) 87 self._conn.connect(self.settings.socket_address) 88 self.send_message_b(self.settings.keyword) 89 if self.read_message_b() != self.server_answer__keyword_accepted: 90 raise SimpleTcpLinkError('Server rejected the keyword: {}.'.format( 91 self.settings.keyword)) 92 else: 93 raise NotImplementedError('Unknown ConnectionType.') 94 95 if self.use_nodelay_inet and (self._conn.family in INET_TYPE_CONNECTIONS): 96 self._conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
@contextmanager
def
simple_tcp_link_connect(simple_tcp_obj):