Socket服务器实现多个客户端通信

本文节选自我的博客:Socket 服务器实现多个客户端通信

  • 作者简介:大家好,我是MilesChen,偏前端的全栈开发者。
  • CSDN主页:爱吃糖的猫
  • 我的博客:爱吃糖的猫
  • Github主页: MilesChen
  • 支持我:点赞+收藏⭐️+留言
  • 介绍:The mixture of WEB+DeepLearning+Iot+anything

前言

由于没有公网IP,实现非局域网的Socket通信极为困难,将Socket服务端部署在服务器上,实现多个客户端相互转发可解决。


提示:以下是本篇文章正文内容,下面案例可供参考

一、实验环境

云服务器:ubuntu18.4----python3.6
客户端PC:windows10—python3.7
客户端TX2:ubuntu18.4—python3.6

二、实验步骤

1.服务器配置

1.注册购买服务器套餐,点击示例可查看到当前内外网的IP
Socket服务器实现多个客户端通信_第1张图片
2.安装VNC远程 配置安全组(不装桌面不配置VNC也可以):
[先安装桌面] (https://zhuanlan.zhihu.com/p/151314336)
[安装VNC](https://zhuanlan.zhihu.com/p/152044577)
VNC无法远程的解决办法,注意重启
注意 配置安全组 配置为允许访问所有端口,方便省事

运行在服务器BaiDuserver.py:

import socketserver  #支持多个客户端   无限发送

client_state = {'PC': 0,'TX2': 0}   #PC和TX2的ip的对象
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(4096).strip()
                receved_string=self.data.decode("utf-8")
                if client_state['TX2']!=0 and client_state['PC']!=0 and len(receved_string)!=0 and receved_string!='AT+PCstart' and receved_string!='AT+TX2start':
                    client_state['TX2'].request.send('ok'.encode("utf-8"))
                    client_state['PC'].request.send(client_state['TX2'].data)

                if receved_string=='AT+PCstart':
                    client_state['PC']=self
                    print("PC connected")
                    if client_state['TX2'] != 0 and client_state['PC'] != 0:   #检测是否都连上了
                        client_state['TX2'].request.send('PCready'.encode("utf-8"))
                        client_state['PC'].request.send('TX2ready'.encode("utf-8"))
                elif receved_string=='AT+TX2start':
                    client_state['TX2']=self
                    print("TX2 connected")
                    if client_state['TX2'] != 0 and client_state['PC'] != 0:   #检测是否都连上了
                        client_state['TX2'].request.send('PCready'.encode("utf-8"))
                        client_state['PC'].request.send('TX2ready'.encode("utf-8"))
            except Exception  as e:
                print("err:",e)
                try:
                    client_state['TX2'].request.send('AT+disconnect'.encode("utf-8"))
                except Exception  as e:
                    print("TX2需要手动重连:",e)
                try:
                    client_state['PC'].request.send('AT+disconnect'.encode("utf-8"))
                except Exception  as e:
                    print("PC需要手动重连:",e)
                client_state['PC']=0
                client_state['TX2']=0
                break
if __name__ == "__main__":
    HOST, PORT = '172.16.0.4', 8080      #172.16.0.4     localhost
    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
    server.serve_forever()

2.客户端配置

PCclient.py:

import socket
import time
client = socket.socket()

def connect_server():
    while True:
        try:
            client.connect(('106.13.47.79', 8080))  # 106.13.47.79   localhost
            break
        except Exception  as e:
            time.sleep(1)
            print("服务器没开", e)
    client.send('AT+PCstart'.encode("utf-8"))
    print("等待TX2连接中...")

connect_server()
data = client.recv(1024).strip()  # 设置收多少字节
if data.decode("utf-8")=='TX2ready':
    print("开始接收...")
    while True:
        receved_string= client.recv(1024).decode("utf-8")                          #设置收多少字节
        print("recv:",receved_string)
        if receved_string == 'AT+disconnect':
            client.send('AT+PCstart'.encode("utf-8"))
            print("等待TX2连接中...")
            data = client.recv(1024).strip()  # 设置收多少字节
            if data.decode("utf-8") == 'TX2ready':
                print("开始接收...")

        # f = open("test.txt", 'a', encoding="utf-8")
        # f.write(receved_string)
        # f.write("\n")
        # f.close()
client.close()

TX2client.py:

import socket
import time

client = socket.socket()
def connect_server():
    while True:
        try:
            client.connect(('106.13.47.79', 8080))  # 106.13.47.79   localhost
            break
        except Exception  as e:
            time.sleep(1)
            print("服务器没开", e)
    client.send('AT+TX2start'.encode("utf-8"))
    print("等待PC连接中...")
connect_server()
data = client.recv(1024).strip()  # 设置收多少字节
if data.decode("utf-8")=='PCready':
    print("开始发送...")
    send_num=0
    while True:
        try:
            send_str='TX2test: %s'%(str(send_num))
            client.send(send_str.encode("utf-8"))      #转二进制并发送
            print("send:",send_str)
            receved_string = client.recv(1024).decode("utf-8")     #设置收多少字节  接收带数据会收到  ok
            #print("recv:",receved_string)

            if receved_string == 'AT+disconnect':
                while  True:
                    client.send('AT+TX2start'.encode("utf-8"))
                    print("等待PC连接中...")
                    data = client.recv(1024).strip()  # 设置收多少字节
                    if data.decode("utf-8") == 'PCready':
                        print("开始发送...")
                        send_num = 0
                        break

            time.sleep(1)
            send_num=send_num+1
        except Exception  as e:
            print("出错:", e)
            client.send('AT+TX2start'.encode("utf-8"))
            print("等待PC连接中...")
            data = client.recv(1024).strip()  # 设置收多少字节
            print("error:",data)
            if data.decode("utf-8") == 'PCready':
                while  True:
                    client.send('AT+TX2start'.encode("utf-8"))
                    print("等待PC连接中...")
                    data = client.recv(1024).strip()  # 设置收多少字节
                    if data.decode("utf-8") == 'PCready':
                        print("开始发送...")
                        send_num = 0
                        break
client.close()

3.修改IP和端口

服务器的IP为服务器的内网IP,端口随意
客户端的IP为服务器的公网IP,端口同服务器的端口

三、效果展示

服务器启动后,当有设备连接会输出连接信息
Socket服务器实现多个客户端通信_第2张图片
PC客户端启动后,会输出等待TX2连接
Socket服务器实现多个客户端通信_第3张图片
TX2和PC同时启动后 TX2会输出一下信息,send后为发送的信息
Socket服务器实现多个客户端通信_第4张图片
PC端会接收到如下信息
Socket服务器实现多个客户端通信_第5张图片
PC主动断开连接,服务端和TX2客户端做了异常处理,当PC重新连接后恢复通信
Socket服务器实现多个客户端通信_第6张图片

总结

  1. 上面实现了两个客户端利用百度云服务器上的服务端进行通信,多个客户端也是同理。
  2. 可以一以此为架构,做成更加、通用的业务,解决无公网IP的IP的各个设备无法通信问题

有任何疑问和想法,欢迎在评论区与我交流。

你可能感兴趣的:(python,服务器,运维,http,socket,python)