Rtthread OS 功能开发之 socket tcp协议程序开发

在使用ART -PI 硬件开启WiFi联网之后,就可以进行TCP和UDP协议编程了。ART-PI WIFI联网方法

在Settings 中查看网络选项中是否选中了以下的三层。

随后再查看以下选择项是否正常启动。一般来说这些是默认打开的。

确保以上项都已经选择后。新建一个文件 tcp_client.c:

cpp 复制代码
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2026-10-16     yinchenxi       the first version
 */
#include <rtthread.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

rt_thread_t rth_tcp_send;
rt_thread_t rth_tcp_recv;

#define SERVER_HOST "192.168.137.1"
#define SERVER_PORT 8888

typedef struct{
    int sock;
    struct sockaddr_in server_addr;
    struct hostent   *host;
}TCP_Sock;

int sendcnt = 0;

static void tcp_client_recv_entry(void *parameter)
{
    TCP_Sock *tcpsock = (TCP_Sock*)parameter;
    char recv_buf[256];
    int recv_len;

    while (1)
    {
        memset(recv_buf, 0, sizeof(recv_buf));
        recv_len = recv(tcpsock->sock, recv_buf, sizeof(recv_buf) - 1, 0);

        if (recv_len > 0)
        {
            rt_kprintf("TCP received %d bytes: %s\n", recv_len, recv_buf);
        }
        else if (recv_len == 0)
        {
            rt_kprintf("Server closed connection\n");
            break;
        }
        else
        {
            rt_kprintf("TCP recv failed\n");
            break;
        }

        rt_thread_mdelay(100);
    }
}

static void tcp_client_send_entry(void* paramter)
{

    TCP_Sock *tcpsock  = (TCP_Sock*)paramter;
    char send_buf[128];
    int  send_len;
    while(1)
    {
        sendcnt ++;
        rt_snprintf(send_buf,sizeof(send_buf),"Hello From ART-Pi Client%d",sendcnt);

       send_len  = send(tcpsock->sock, send_buf, strlen(send_buf), 0);

       if(send_len > 0)
       {
           rt_kprintf("TCP send successful %d bytes send \n",send_len);
       }
       else {
           rt_kprintf("TCP send failed,code = %d\n",errno );
       }

       rt_thread_mdelay(1500);
    }
}

static TCP_Sock tcpsock;

void rth_tcp_create(void)
{
    rt_memset(&tcpsock, 0, sizeof(tcpsock));

    tcpsock.sock = socket(AF_INET,SOCK_STREAM,0);

    if(tcpsock.sock == -1)
    {
        rt_kprintf("Create socket error\n");
        return ;
    }

    tcpsock.server_addr.sin_family = AF_INET;
    tcpsock.server_addr.sin_port   = htons(SERVER_PORT);
    tcpsock.server_addr.sin_addr.s_addr = inet_addr(SERVER_HOST);


    rt_memset(&(tcpsock.server_addr.sin_zero),0 ,sizeof(tcpsock.server_addr.sin_zero));


    rt_kprintf("Connect to %s : %d ... \n",SERVER_HOST,SERVER_PORT);

    if(connect(tcpsock.sock,(struct sockaddr*)&tcpsock.server_addr,sizeof(struct sockaddr)) == -1)
    {
        rt_kprintf("Connect failed\n");

        closesocket(tcpsock.sock);
        return ;
    }
    rt_kprintf("Connnected to server successful\n");

    rth_tcp_recv = rt_thread_create("tcp_recv", tcp_client_recv_entry, &tcpsock, 2048, 5, 100);
    rth_tcp_send = rt_thread_create("tcp_send", tcp_client_send_entry, &tcpsock, 2048, 6, 100);

    rt_thread_startup(rth_tcp_recv);
    rt_thread_startup(rth_tcp_send);


}

MSH_CMD_EXPORT(rth_tcp_create,"tcp test");

电脑端使用Python做TCP服务器程序并开启服务。

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading
import datetime

# ================= 配置 =================
HOST = '0.0.0.0'      # 监听所有网卡,允许外部设备连接
PORT = 8888           # 监听端口,需与 ART-Pi 客户端一致
BUFSIZE = 1024        # 接收缓冲区大小
# ========================================

def handle_client(conn, addr):
    """处理单个客户端连接"""
    print(f"[{datetime.datetime.now()}] 新连接: {addr}")
    try:
        while True:
            # 接收数据
            data = conn.recv(BUFSIZE)
            if not data:
                print(f"[{datetime.datetime.now()}] 客户端 {addr} 断开连接")
                break

            # 打印接收到的数据(尝试解码为 UTF-8)
            try:
                text = data.decode('utf-8')
                print(f"[{datetime.datetime.now()}] 收到来自 {addr} 的数据: {text.strip()}")
            except UnicodeDecodeError:
                print(f"[{datetime.datetime.now()}] 收到来自 {addr} 的二进制数据: {data.hex()}")

            # 回复客户端
            reply = f"Server received: {text.strip()}\n"
            conn.sendall(reply.encode('utf-8'))
            print(f"[{datetime.datetime.now()}] 已回复 {addr}: {reply.strip()}")

    except ConnectionResetError:
        print(f"[{datetime.datetime.now()}] 客户端 {addr} 强制断开")
    except Exception as e:
        print(f"[{datetime.datetime.now()}] 处理 {addr} 时出错: {e}")
    finally:
        conn.close()
        print(f"[{datetime.datetime.now()}] 连接 {addr} 已关闭")

def start_server():
    """启动 TCP 服务器"""
    # 创建 TCP 套接字
    server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口复用,避免重启时"Address already in use"
    server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定地址和端口
    server_sock.bind((HOST, PORT))
    # 开始监听,最大等待连接数 5
    server_sock.listen(5)

    print(f"TCP 服务器已启动,监听 {HOST}:{PORT}")
    print("等待 ART-Pi 连接... (按 Ctrl+C 退出)")

    try:
        while True:
            # 接受客户端连接
            conn, addr = server_sock.accept()
            # 为每个客户端创建一个线程
            client_thread = threading.Thread(target=handle_client, args=(conn, addr))
            client_thread.daemon = True
            client_thread.start()
    except KeyboardInterrupt:
        print("\n服务器正在关闭...")
    finally:
        server_sock.close()
        print("服务器已关闭")

if __name__ == '__main__':
    start_server()

测试如下:ART_PI 作为TCP客户端。

电脑开启WiFi热点后作为服务端:

相关推荐
Brookty1 小时前
网络原理|第三阶段:MTU、TCP 分段、IPv4 分片与重组及路径 MTU 发现
网络·ip
wjkjpcba1 小时前
工业以太网通信板PCBA厂家怎么选?接口器件与焊接工艺解析
网络·smt贴片加工·pcba贴片加工厂·机器人pcba
byte轻骑兵1 小时前
【LMP】规范精讲[6]: 从陌生到互信——安全简单配对(SSP)的四步握手
网络协议·蓝牙协议·lmp·蓝牙链路管理
AbandonForce1 小时前
Linux 网络:HTTP(一)基础与报文结构
linux·网络·http
乐橙开放平台1 小时前
门店监控想集中看?乐橙含光支持多品牌摄像头跨店管理
网络·笔记·物联网·自动化·音视频·智能家居
weixin_417396831 小时前
监控画面卡顿与录像缺失:码率、NVR与存储容量的排查顺序
前端·网络·技术·酒店·综合布线·弱电
pt10431 小时前
Cisco设备网络安全系列-10:思科混合办公、终端、物联网与多云数据中心
网络·物联网·安全
权球物联国际流量服务1 小时前
比利时物联网卡选型:至少确认Band20,4个频段+2种网络制式怎么配?
网络·物联网
2301_777998345 小时前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存