Python中socket通信

该代码示例展示了如何使用Python创建一个TCPSocket服务器,服务器端对发送的数据进行简单的校验,通过在数据前添加标志位来确保数据完整性。客户端接收到数据后,会检查数据的完整性。此外,服务器还包含了心跳检测功能,用于判断客户端连接是否存活。客户端则将接收到的字典数据保存到txt文件中。
摘要由CSDN通过智能技术生成

main函数自定义,针对个人需求处理发送的消息和接收的数据,以下是Server,为了保证传输的数据完整性,增加简单的数据校验,在发送的数据前加标志位,如:#234,代表以#开始,#后一位数代表后面34的长度为2,34则代表发送的数据的长度。

import json
import socket
import threading
import time
from socket import AF_INET, SOCK_STREAM
from typing import Union


class SocketServer:
    def __init__(self, ip: str, port: int):
        # 一般大写字母用来表示配置信息
        self.server = None
        self.client_address = None
        self.client_socket = None
        self.SERVER_IP = ip
        print(self.SERVER_IP)
        self.SERVER_PORT = port
        self.BUF_LEN = 1024  # 一次性接受的最大字节数
        self.__start_server()

        self.__keep_runing = True
        threading.Thread(target=self.__ping_clients).start()

    def __start_server(self):
        self.server = socket.socket(AF_INET, SOCK_STREAM)  # 监听端口,使用INET即为网络层使用IP协议,STREAM表示传输层使用TCP协议
        self.server.bind((self.SERVER_IP, self.SERVER_PORT))  # 监听端口需要绑定ip地址和端口号,bind中只能是一个参数,因此使用元组传参
        self.server.listen(5)  # 最多接受五个等待连接的客户端

    def __wait_client(self):
        client_socket, client_address = self.server.accept()  # 等待新客户端连接
        print("连接已建立:", client_address)
        self.client_socket = client_socket
        self.client_address = client_address

    def send(self, data):
        """
        仅仅发送消息,无需等待返回值
        :param data:
        :return:
        """
        msg_length = str(len(data))
        command = f"#{len(msg_length)}{msg_length}{data}"
        self.client_socket.sendall(command.encode("utf-8"))

    def recvive(self):
        # 接收客户端的消息
        data = self.client_socket.recv(self.BUF_LEN)
        if not data:  # 连接已关闭
            return None
        else:
            message = data.decode("utf-8")
            print("收到客户端消息:", message)
            return message

    def __ping_clients(self):
        """
        判断连接是否存活
        """
        while self.__keep_runing:
            if self.client_socket:
                try:
                    self.send("ping")
                except socket.error:
                    # Client is most likely disconnected
                    print("连接已关闭:", self.client_address)
                    self.client_socket = None
                    self.client_address = None
            else:
                ...
            time.sleep(5)
        else:
            print(f"线程停止!")

    def send_msg(self, command: Union[dict, str]):
        """
        发送消息并等待返回
        :param command:
        :return:
        """
        if isinstance(command, dict):
            command = json.dumps(command)
        else:
            ...

        while True:
            if self.client_socket:
                self.send(command)
                # 接收客户端的消息
                message = self.recvive()
                if message == 'ok':
                    # 回复客户端
                    response = f"已收到消息:{message}"
                    self.send(response)
                    break
                elif message == 'no':
                    print(f"Send again")
                    time.sleep(3)
                    continue
                else:
                    break
            else:
                self.__wait_client()
                continue

    def close(self):
        self.__keep_runing = False
        self.client_socket.close()
        self.server.close()


def main():
    server = SocketServer('127.0.0.1', 8888)
    cmd = {'start_test': ''}
    server.send_msg(cmd)
    time.sleep(10)
    server.send_msg('close')
    server.close()


if __name__ == '__main__':
    main()

Client客户端,将接收到的字典保存到txt中

import threading
import time
from pathlib import Path
from socket import socket



TXT_PATH = Path.cwd() / 'data.txt'


class SocketClient:
    def __init__(self, server_ip: str, server_port: int):
        self.command = None
        self.BUF_LEN = 1024
        self.server_socket = socket()
        server_address = (server_ip, server_port)
        self.server_socket.connect(server_address)
        self.keep_running = True

    def start_receive(self):
        threading.Thread(target=self.__receive_ping).start()

    def send(self, msg):
        self.server_socket.send(msg.encode())

    @staticmethod
    def __check_data(data: str):
        """
        检查收到的信息是否完整
        :param data:
        :return:
        """
        idx = data.find('#')
        length_of_data_len = int(data[idx + 1])
        data_length = int(data[idx + 2: idx + 2 + length_of_data_len])
        msg = data[idx + 2 + length_of_data_len:]
        if len(msg) == data_length:
            return msg
        else:
            return False

    def __receive_ping(self):
        """
        接收心跳信息
        """
        while self.keep_running:
            recv_data = self.server_socket.recv(self.BUF_LEN).decode()  # 发送完数据,等待接受不超过1024字节的回应数据
            msg = self.__check_data(recv_data)
            if msg is False:
                self.send('no')
                continue
            elif msg == 'ping' or not recv_data:
                ...
            elif msg == '已收到消息:ok':
                pass
            elif msg == 'close':
                self.command = msg
                self.close()
                break
            else:
                self.command = msg
                print(msg)
                self.__save_task_to_txt(msg)
                self.send('ok')
        else:
            print(f'线程停止!')

    @staticmethod
    def __save_task_to_txt(msg: str):
        data = eval(msg)
        if type(data) != dict:
            return
        with open(TXT_PATH, 'w') as f:
            for func in data:
                f.write('{'+f"'{func}': '{data[func]}'"+'}\n')

    def close(self):
        self.keep_running = False
        self.server_socket.close()

def main():
    ip = '127.0.0.1'
    client = SocketClient(ip, 8888)
    client.start_receive()  # 开启线程接收消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pythonsocket通信是一种在网络传输数据的方式,通过套接字(socket)来实现。它可以用于实现不同计算机之间的数据传输和通信。 要使用Python进行socket通信,首先需要导入socket模块。然后,可以创建一个socket对象,并指定通信协议(如TCP或UDP),以及IP地址和端口号。接着,可以使用socket对象的一些方法来发送和接收数据。 下面是一个简单的例子,演示了如何使用Pythonsocket模块进行客户端和服务器端的通信: 服务器端代码: ```python import socket # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 server_socket.bind(('localhost', 8888)) # 监听客户端连接 server_socket.listen(5) print('服务器启动成功,等待客户端连接...') # 接受客户端连接 client_socket, addr = server_socket.accept() print('客户端已连接:', addr) # 接收客户端发送的数据 data = client_socket.recv(1024) print('接收到的数据:', data.decode()) # 发送响应给客户端 client_socket.send('Hello, Client!'.encode()) # 关闭socket连接 client_socket.close() server_socket.close() ``` 客户端代码: ```python import socket # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 client_socket.connect(('localhost', 8888)) # 发送数据给服务器 client_socket.send('Hello, Server!'.encode()) # 接收服务器的响应 data = client_socket.recv(1024) print('接收到的数据:', data.decode()) # 关闭socket连接 client_socket.close() ``` 在这个例子,服务器端首先创建一个socket对象,并绑定IP地址和端口号。然后通过调用`listen()`方法开始监听客户端连接。当有客户端连接请求时,使用`accept()`方法接受连接,并返回一个新的socket对象和客户端地址。接着,服务器端可以通过新的socket对象与客户端进行通信。 客户端先创建一个socket对象,并调用`connect()`方法连接到服务器。然后,可以使用`send()`方法发送数据给服务器,并使用`recv()`方法接收服务器的响应。 相应问题: 1. 如何指定TCP或UDP协议? 2. 还有其他的socket创建方式吗? 3. 如何处理多个客户端同时连接的情况? 4. 如何实现长连接?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值