吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1124|回复: 11
收起左侧

[求助] python socket 服务程序求大助

[复制链接]
Vigoss802 发表于 2022-10-12 23:31
40吾爱币
需要用python 需要做一个获取几个设备状态数据的服务程序,本人小白熬了一个月,碰到线程实在搞不定,需要高手支持写个框架。万分感谢。


服务端需要创建两个socket
hostip = '192.168.123.456'
port1 = 12345
port2 = 67890

server1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server1.bind((hostip, port1))
server1.listen(2)   

server2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server2.bind((hostip, port1))
server2.listen(2)

# 这里server1 可收发数据,server2只接受数据


设备特性
设备启动后会主动connect端口1,server1.accept到后发送
<msg>
    <cmd>CONNECT</cmd>
    <data>
    </data>
</msg>
到设备,设备会反馈
<msg>
    <cmd>CONNECT</cmd>
    <data>
        <return>OK</return>
        <name>device_A</name>
    </data>
</msg>
且设备会同时会去connect端口2,server2.accept后可接受机床和上面一样的数据报告设备名称。
然后设备会反馈当前设备状态到server2.
<msg>
    <cmd>STATE</cmd>
    <data>
        <A>FALSE</A>
        <B>TRUE</B>
        <ERROR>FALSE</ERROR>
    </data>
</msg>

设备状态数据如果将来出现变化,会主动发给server2



服务端:
server1与设备的通讯是发一个反馈一个

<msg>
    <cmd>指令</cmd>
    <data>
    </data>
</msg>

<msg>
    <cmd>指令</cmd>
    <data>
        <return>OK</return>    #NOK
        ...                                      #......
    </data>
</msg>

server1需要每60秒发一个WATCHDOG指令给设备,确保设备没死机。
另外还有个server1还要根据设备某些状态发送特定指令给设备获取数据。  
例如当状态<ERROR>TRUE</ERROR>时发送GETERRORS,机床反馈ok的同时会带错误列表。


这个服务器需要连接多个设备。 也需要支持设备重启后重连。  







发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

dork 发表于 2022-10-13 11:24
其实完全不用这个思路,换一个吧
flask  fastAPI都可以更好的实现你的要求。比你这C/S要好一些
wihn 发表于 2022-10-13 12:29
不要自己手写socket了,这样既麻烦,而且性能比不上众多大神写的\优化过的框架。这不是HTTP协议,因此我认为fastAPI这类框架不适用。可以看看SocketServer这个库,这是Python自带的,非底层的TCP框架。
littleworm 发表于 2022-10-13 13:07
 楼主| Vigoss802 发表于 2022-10-13 13:50
dork 发表于 2022-10-13 11:24
其实完全不用这个思路,换一个吧
flask  fastAPI都可以更好的实现你的要求。比你这C/S要好一些

设备是死的,所以没办法。
 楼主| Vigoss802 发表于 2022-10-13 13:51
wihn 发表于 2022-10-13 12:29
不要自己手写socket了,这样既麻烦,而且性能比不上众多大神写的\优化过的框架。这不是HTTP协议,因此我认 ...

谢谢指点,有想过还是玩不转。
chr_233 发表于 2022-10-13 14:52
分享一个之前写的课设作业,这是main.py,使用select来异步建立socket连接和收发socket数据
然后由TCPHandler处理消息,之前用的是json,要用xml的话自己写就是了
另外感觉没必要开两个端口,消息可以用cmd区分类型,用一个socket足以
[Python] 纯文本查看 复制代码
import select
import socket
import sys
from queue import Empty, Queue
from socket import socket as Socket

from core.tcp_handler import TCPHandler
from core.utils import log

LISTEN_ON = '0.0.0.0'

RECV_BYTES = 8192



def main(host, port):
    # Init TCP server
    tcp_socket = Socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_socket.setblocking(False)
    try:
        tcp_socket.bind((host, port))
        tcp_socket.listen(10)
        log(f'TCP server listening on {host}:{port}', None, False)
    except OSError as s:
        log(f'TCP server start error: {s}', None, True)
        return

    # Init TCPHandler
    tcp_handler = TCPHandler()

    log('Wating for clients ...', None, False)

    # Event loop
    try:
        inputs = [tcp_socket, ]
        outputs = []
        msg_queue = {}
        while True:

            rlist, wlist, elist = select.select(inputs, outputs, inputs, 1)
            for s in rlist:
                # any socket is ready for reading
                if s == tcp_socket:
                    # TCP incoming connection
                    conn, addr = s.accept()
                    conn.setblocking(False)

                    inputs.append(conn)
                    msg_queue[conn] = Queue()
                    # log('TCP connection established', addr, False)

                else:
                    data = s.recv(RECV_BYTES)
                    addr = s.getpeername()
                    if data:
                        # TCP message
                        response = tcp_handler.handle_message(data, addr)
                        msg_queue[s].put(response)
                        if s not in outputs:
                            outputs.append(s)
                    else:
                        # TCP close
                        # log('TCP connection closed', addr, True)
                        if s in outputs:
                            outputs.remove(s)
                        inputs.remove(s)
                        s.close()
                        msg_queue.pop(s, None)

            for s in wlist:
                # any socket is ready for writing
                try:
                    payload = msg_queue[s].get_nowait()
                    s.send(payload)
                    outputs.remove(s)
                    msg_queue.pop(s, None)
                except Empty:
                    pass

            for s in elist:
                # any socket raises error
                log('TCP connection error', None, True)

                inputs.remove(s)
                if s in outputs:
                    outputs.remove(s)

                msg_queue.pop(s, None)

                s.close()

    except KeyboardInterrupt:
        pass
    finally:
        tcp_socket.close()
        log('Server shutdown ...', None, True)


if __name__ == '__main__':

    try:
        port = int((sys.argv[1:] or ['12345'])[0])
        if port < 0 or port > 65535:
            raise ValueError
    except ValueError:
        log('Usage: python3 server.py [port]', None, True)
        log('Default port is 12345', None, True)
        input('Press enter to exit...')
        exit(1)

    main(LISTEN_ON, port)


[Python] 纯文本查看 复制代码
class TCPHandler():

    def handle_message(self, raw: bytes, addr: Tuple[str, int]):
    try:
        response = None
        # addr = sock.getpeername()
        payload = json_deserializer(raw)
        # 这里处理消息
    except:
        pass
chr_233 发表于 2022-10-13 14:53
本帖最后由 chr_233 于 2022-10-13 14:58 编辑
chr_233 发表于 2022-10-13 14:52
分享一个之前写的课设作业,这是main.py,使用select来异步建立socket连接和收发socket数据
然后由TCPHand ...

完整源码是一个基于UDP的简单的论坛程序,没什么关联,就不放了

image.png

image.png
zsjalive 发表于 2022-10-13 15:54
chr_233 发表于 2022-10-13 14:53
完整源码是一个基于UDP的简单的论坛程序,没什么关联,就不放了

基于UDP的论坛程序源码能不能放出来,学习学习。
chr_233 发表于 2022-10-13 16:01
zsjalive 发表于 2022-10-13 15:54
基于UDP的论坛程序源码能不能放出来,学习学习。

课设而已,没什么实际用途
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 05:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表