python-3.x - Python套接字客户端在2分钟后断开连接

标签 python-3.x sockets

我编写了一个简单的 python 服务器和客户端,但由于某种原因通信意外关闭。

我运行 WireShark 来跟踪客户端正在做什么,我发现 2 分钟后客户端无缘无故地发送了一个 RST 包。

我期望的行为是:

  1. 工程师客户端向服务器发送数据(这里没问题)
  2. 服务器接收数据并等待Press客户端
  3. 按客户端连接到服务器发送其 DCU(客户端 ID)并 询问是否有他的信息,如果没有,新闻客户端会保持联系 服务器等待数据。

服务器:

import socketserver
import socket
import pickle


list_changes = []
list_dcu = set()

def connections(server):
    conns = []
    addrs = []
    server.listen() # Server is listening

    while True:
        my_socket, addr = server.accept()
        data_recv = pickle.loads(my_socket.recv(4096))
        server.setblocking(1)
        conns.append(my_socket)
        addrs.append(addr)

        # Registering, Appending and Search
        if data_recv[0] == 'DCU':
            try:
                append_dcu(data_recv)
                search_changes(data_recv)
            except IndexError:
                print('errrrrrrror')
        elif data_recv[0] == 'ING':
            list_changes.append(data_recv)

def append_dcu(data_recv): # Appending function
    list_dcu.add(data_recv[1])
    print('List DCU: ', list_dcu)
    return

def search_changes(data_recv): # Search for DCU in list_changes and send data if found
    i = 0
    for i in range(len(list_changes)):
        if data_recv[1] == list_changes[i][2]:
            response = pickle.dumps(list_changes[i])
            request.sendall(response)
            del list_changes[i]
    return


if __name__ == "__main__":
    host, port = "127.0.0.1", 9999
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, port))
    connections(server)

客户:

import socket
import pickle
import threading
from view import MainView, msg_alert


class AppInit:

    def __init__(self):
        self.controller = Controller()
        self.view = MainView(self.controller)
        return


class Controller:

    def __init__(self):
        # self.th1 =
        return

    class Threading:
        def __init__(self, var_dcu):
            self.host = '127.0.0.1'  # my_socket IP - Change it in Test Environment
            self.port = 9999
            self.var_dcu = var_dcu
            self.data = ''
            self.data_send = 0
            self.th1 = threading.Thread(target=search, args=(self.var_dcu, self.host, self.port))
            self.th1.daemon = True
            self.th1.start()

def search(var_dcu, host, port):
    data = ('DCU', var_dcu)
    data_send = pickle.dumps(data)
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    my_socket.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 10000, 3000))
    my_socket.connect(('127.0.0.1', 9999))
    my_socket.sendall(data_send)

我使用的是 Python 3.7

提前致谢。任何帮助将不胜感激

最佳答案

正如我所说,我尝试使用 keepalive 和那些东西,但由于某种原因,客户端在 2 分钟后不断向服务器发送 RST,所以我改变了客户端的行为。

客户端:向服务器请求更改 服务器:使用更改列表进行响应,如果没有更改,则使用特殊字符串进行响应。 客户端:收到响应,它会执行任何操作并关闭连接。

2 分钟后,循环会自行重复

代码时间:

服务器:

import socket
import pickle
import time


class Main:

    def __init__(self):
        # self.list_changes is filled with 2 examples from Engineering client
        self.list_changes = [['ING', 'Chris', '432', 1122, 'Reason 1'],
                             ['ING', 'Jane', '431', 8899, 'Reason 2']]
        self.dict_dcu = {}
        self.host = None
        self.port = None
        self.server_socket = None

        self.server()

    def server(self):
        self.host, self.port = "127.0.0.1", 9999
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((self.host, self.port))
        self.server_socket.listen() # Servidor en estado de escucha

        while True:
            self.client_sock, self.addr = self.server_socket.accept()
            self.data_recv = pickle.loads(self.client_sock.recv(4096))
            self.appending()

    def appending(self):
        if self.data_recv[0] == 'DCU':
            try:
                self.dict_dcu.update({self.data_recv[1]: self.client_sock})
                self.search_changes()
            except IndexError as error:
                print('Error: ', IndexError)
        if self.data_recv[0] == 'ING':
            try:
                self.list_changes.append(self.data_recv)
            except IndexError as error:
                print('Error :', error)
                return

    def search_changes(self):
        self.key = self.data_recv[1]
        for i in range(len(self.list_changes)):
            if self.key == self.list_changes[i][2]:
                self.key = self.dict_dcu.get(self.data_recv[1])
                self.sendmsg(self.key, self.list_changes[i])
                self.list_changes.pop(i)
                break
            elif i+1 == len(self.list_changes):
                self.sendmsg(self.key, 'No_changes')

    def sendmsg(self, socket_key, message):
        self.updates = pickle.dumps((message))
        self.client_sock.sendall(self.updates)


if __name__ == "__main__":
    main = Main()

客户:

import socket, pickle, time, threading
import view
from tkinter import messagebox
import _thread


class AppInit:
    def __init__(self):

        self.controller = Controller(view.MainView)


class Controller:
    def __init__(self, mainview):
        self.bttn = view.MsgReceiver.bttn_state
        self.main_view = mainview

        # Changes vars
        self.name = None
        self.job = None
        self.reason = None

        # DCU related vars
        self.dcu = None
        self.reg_dcu = None

        # Socket variables
        self.send_sock = None
        self.response = None
        self.addr = None
        self.listen_port = None

        self.start_app()

    def start_app(self):
        self.main_view(self.threading)

    def threading(self, dcu, bttn):
        try:
            _thread.start_new_thread(self.fetching_changes, (dcu, bttn))
        except _thread.error:
            messagebox.showerror('ERROR THREADING', 'UNABLE TO START THREAD')

    def fetching_changes(self, dcu, bttn):
        self.bttn = bttn
        self.dcu = ['DCU', dcu]
        self.reg_dcu = pickle.dumps(self.dcu)
        while True:
            self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                self.send_sock.connect(('127.0.0.1', 9999))  # Replace IP addr with IP Rad server
                self.bttn.configure(text='Connected')
                self.bttn['state'] = 'disable'
            except ConnectionRefusedError:
                messagebox.showerror('CONNECTING ERROR', 'UNABLE TO CONTACT SERVER, PLEASE CALL.\n '
                                                         '-ALBERTO TREVIÑO - CELL: 123 12345')
                self.bttn.configure(text='Connect')
                self.bttn['state'] = 'active'
                break
            self.send_sock.setblocking(True)
            self.send_sock.sendall(self.reg_dcu)
            self.response = pickle.loads(self.send_sock.recv(1024))
            if self.response != 'No_changes':
                self.name = self.response[1]
                self.job = str(self.response[3])
                self.reason = str(self.response[4])
                messagebox.showwarning('CHANGE ALERT', self.name + ' changed something in JOB: ' + self.job
                                       + " Reason:\n " + self.reason)
            else:
                print('No changes')
            self.send_sock.shutdown(socket.SHUT_RDWR)
            self.send_sock.close()
            time.sleep(10)

我希望有人觉得它有用。

关于python-3.x - Python套接字客户端在2分钟后断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63553449/

相关文章:

ios - Openfire 服务器发送空数据包

Python icmp 套接字服务器(不是 tcp\udp)

python - 在 tensorflow 中使用 bool 张量选择张量的子集

python - 如何构建一个检测 2 个列表上交叉点的函数

python-3.x - 如何将列的值设置为数据框中的列?

c++ - 如何获取本地计算机的 IP 地址?

c - 在c中用套接字传输和验证证书(openssl)

c - 在 c 中通过 TCP 发送 MQTT 连接数据包

python - 从 python3 检索 jinja2 模板变量

python - 将多个循环输出添加到单个字典