Я экспериментирую с сокетами.
Я установил простой прослушиватель netcat и у меня есть следующий код python.
Я создаю сокет TCP и устанавливаю его без блокировки после настройки Параметры поддержки активности TCP.
Когда слушатель уничтожен, соединение переходит в состояние «close_wait».
При первом вызове socket.send данные соединения close_wait отправляются в буфер .
Во второй раз метод "socket.send" вызывается как исключение "Broken Pipe".
Такое поведение приводит к потере данных.
Из-за характера предполагаемого приложения I Я не могу создать фрейм на уровне приложения для подтверждения доставки.
# snip from code
class TCPSocketHandler(SocketHandler):
# init etc ...
def connect(self):
self.socket = socket.socket(socket.AD_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
self.socket.connect((self.dst_host, self.dst_port))
self.socket.setblocking(0)
return self.socket
def _get_socket(self):
if not self.socket:
self.socket = self.connect()
return self.socket
def send(self, bytes):
sent = 0
try:
socket = self._get_socket()
# this does not seem to detect sockets in close_wait state
select.select([], [socket], self.timeout_sec)
# first call to this after a socket enters close_wait state causes data loss.
# second call results in broken pipe exception
sent = socket.send(bytes)
except socket.error as e:
err = e.args[0]
if err == errno.EWOULDBLOCK:
time.sleep(0.1)
else:
self.close()
time.sleep(0.5)
return sent
def close(self):
self.socket.close()
self.socket = None
Любая помощь будет принята с благодарностью.