首页 树莓派——tcp_server
文章
取消

树莓派——tcp_server

tcp服务器

想法:主进程中fock一个子进程用来搭建tcp的服务器端,不断的连接tcp客户端,接收和转发处理存储数据,子进程与主进程间使用管道进行通信。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import socket
import threading
from multiprocessing import Pipe
import sqlite1
import select
HOST = '192.168.**.**'
PORT = 8888
commands = {
    'kaimen': lambda: send_to_client("kaimen", "192.168.**.**"),
    'guanmen': lambda: send_to_client("guanmen", "192.168.**.**"),
    'kaichuang': lambda: send_to_client("kaichuang", "192.168.**.**"),
    'guanchuang': lambda: send_to_client("guanchuang", "192.168.**.**"),
    'kaidneg': lambda: send_to_client("kaidneg", "192.168.**.**"),
    'guandeng': lambda: send_to_client("guandeng", "192.168.**.**"),
    'kaichuanglian': lambda: send_to_client("kaichuanglian", "192.168.**.**"),
    'guanchuanglian': lambda: send_to_client("guanchuanglian", "192.168.**.**"),
    'kaixiangxun': lambda: send_to_client("kaixiangxun", "192.168.**.**"),
    'guanxiangxun': lambda: send_to_client("guanxiangxun", "192.168.**.**"),
    'kaizhiwuqi': lambda: send_to_client("kaizhiwuqi", "192.168.**.**"),
    'guanzhiwuqi': lambda: send_to_client("guanzhiwuqi", "192.168.**.**"),
    'kaifengshan': lambda: send_to_client("kaifengshan", "192.168.**.**"),
    'guanfengshan': lambda: send_to_client("guanfengshan", "192.168.**.**"),
}
lock = threading.Lock()
client_sockets = {}

def broadcast_message(message, sender_ip):
    with lock:
        for ip, socket_item in client_sockets.items():
            if ip != sender_ip:
                try:
                    socket_item.send(message.encode())
                except socket.error as e:
                    print(f"Error sending message to {ip}: {e}")

def send_to_client(message, target_ip):
    with lock:
        if target_ip in client_sockets:
            try:
                client_sockets[target_ip].send(message.encode())
            except socket.error as e:
                print(f"Error sending message to {target_ip}: {e}")
        else:
            print(f"Client with IP {target_ip} not found.")

def handle_client(client_socket, client_address):
    with lock:
        client_sockets[client_address[0]] = client_socket
    data_batch = []  # 初始化空列表

    while True:
        request = client_socket.recv(1024)
        if not request:
            break

        message = request.decode()
        print(f"Received from {client_address[0]}:{client_address[1]}: {message}")

        if message.lower().strip() == "quit":
            print(f"Client {client_address[0]}:{client_address[1]} requested to quit")
            break

        if message.startswith("send_to"):
            parts = message.split(":")
            # 格式: send_to:192.168.:fengsan=1
            if len(parts) == 3:
                target_ip = parts[1].strip()
                send_to_client(parts[2], target_ip)
                continue
        if message.startswith("wendu"):
            parts = message.split("&")
            if len(parts) == 6:
                wendu = float(parts[0].strip().split("=")[1])
                shidu = float(parts[1].strip().split("=")[1])
                guangzhao = float(parts[2].strip().split("=")[1])
                co2 = float(parts[3].strip().split("=")[1])
                shengxiang = float(parts[4].strip().split("=")[1])
                fengli = float(parts[5].strip().split("=")[1])
                data_batch.append((wendu, shidu, guangzhao, co2, shengxiang, fengli))  # 将元组添加到列表中

        if len(data_batch) == 2:  # 检查列表中的元组数量是否达到20
            db_path = sqlite1.get_db_path()
            table_name = sqlite1.get_table_name()
            sqlite1.insert_batch_data(db_path, table_name, data_batch)
            data_batch = []  # 清空 data_batch 列表
        # 处理接收到的其他消息
        handle_custom_commands(message, client_address[0])

    with lock:
        del client_sockets[client_address[0]]

    client_socket.close()

def handle_custom_commands(message, sender_ip):
    custom_commands = ["kongtiao", "jiashi", "chuanglian", "jingshi", "fengshan"]

    for command in custom_commands:
        if command in message:
            # 根据需要修改目标 IP
            target_ip = "192.168.**.**"
            send_to_client(message, target_ip)
            return

    # 在这里添加其他处理接收到的消息的逻辑,0例如广播给所有客户端
    broadcast_message(message, sender_ip)


def run_server(pipe):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((HOST, PORT))
    server_socket.listen(5)
    print(f"Server listening on {HOST}:{PORT}")
    server_socket.settimeout(5)  # 设置超时时间为5
    while True:
        try:
            client_socket, client_address = server_socket.accept()
            print(f"Accepted connection from {client_address[0]}:{client_address[1]}")
            
            client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
            client_thread.start()
        except socket.timeout:
            # 如果在超时时间内没有新连接尝试,执行下面的逻辑
            print("\n")
        
        # 继续执行其他逻辑
        ready_sockets, _, _ = select.select([pipe], [], [], 5)  # 等待5秒钟来检查管道是否可读
        if pipe in ready_sockets:  # 如果管道可读
            command = pipe.recv()
            if command in commands:
                commands[command]()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2024-04-27 15:38:53.804 25399-25399 AndroidRuntime          com.example.myapplication            E  FATAL EXCEPTION: main
                                                                                                    Process: com.example.myapplication, PID: 25399
                                                                                                    android.os.NetworkOnMainThreadException
                                                                                                        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
                                                                                                        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116)
                                                                                                        at java.net.SocketOutputStream.write(SocketOutputStream.java:149)
                                                                                                        at com.example.myapplication.JiajuActivity.onItemClick(JiajuActivity.java:291)
                                                                                                        at com.example.myapplication.JiajuListAdapter$MyHolder.onClick(JiajuListAdapter.java:69)
                                                                                                        at android.view.View.performClick(View.java:7322)
                                                                                                        at android.view.View.performClickInternal(View.java:7296)
                                                                                                        at android.view.View.access$3600(View.java:839)
                                                                                                        at android.view.View$PerformClick.run(View.java:28319)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:900)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:103)
                                                                                                        at android.os.Looper.loop(Looper.java:219)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8673)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

几乎都是主线程不能执行网络的命令这类的错误,需要把它弄到线程上执行。

本文由作者按照 CC BY 4.0 进行授权