实现一个服务器同时与多个客户端进行通信

1、accept函数连接到不同客户端的返回值,对应不同客户端的地址

2、利用1中得到的客户端地址作为线程创建时的参数值client_addr,在为与客户端进行数据通信时,client_addr作为recv函数的参数1.

总结,要想同时和多个客户端进行通信,recv函数得知道是那个客户端;还得建立数据通信的线程。

野火F429+RT-Thread TCP服务器连接多客户端同时通信实现方法_通信服务器rtthread-CSDN博客

#include <rtthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#define SERVER_PORT 8080
#define BUFSZ 32
 
/* 服务器的TCP连接处理函数 */
void tcp_server_thread_entry(void *parameter) 
{
    int sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len;
    char buf[BUFSZ];
    int bytes_read;
 
    /* 创建TCP套接字 */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) 
	{
        rt_kprintf("socket create failed\n");
        return;
    }
 
    /* 设置服务器地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
 
    /* 绑定套接字到服务器地址 */
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 
	{
        rt_kprintf("bind failed\n");
        goto __exit;
    }
 
    /* 监听连接请求 */
    if (listen(sock, 5) < 0) 
	{
        rt_kprintf("listen failed\n");
        goto __exit;
    }
 
    client_addr_len = sizeof(client_addr);
    rt_kprintf("Waiting for client connect...\n");
 
    while (1) 
	{
        /* 接受客户端连接 */
        client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_sock >= 0) 
		{
            rt_kprintf("client %s connect\n", inet_ntoa(client_addr.sin_addr));
 
            /* 循环处理与客户端的通信 */
            while (1) 
			{
                /* 接收客户端数据 */
                bytes_read = recv(client_sock, buf, BUFSZ, 0);
                if (bytes_read <= 0) 
				{
                    rt_kprintf("recv failed, bytes_read=%d\n", bytes_read);
                    break;
                }
                buf[bytes_read] = '\0'; /* 确保字符串以null结尾 */
                rt_kprintf("recv data: %s\n", buf);
 
                /* 发送数据回客户端 */
                if (send(client_sock, buf, bytes_read, 0) < 0) 
				{
                    rt_kprintf("send failed\n");
                    break;//直接跳出这一层while,accept新的客户端
                }
            }
 
            /* 关闭与客户端的连接 */
            close(client_sock);
            rt_kprintf("client %s disconnect\n", inet_ntoa(client_addr.sin_addr));
        } 
		else 
		{
            rt_kprintf("accept failed\n");
        }
    }
 
__exit:
    /* 关闭服务器套接字 */
    if (sock >= 0) 
	{
        close(sock);
    }
}
 
/* 在你的应用程序中启动TCP服务器线程 */
int application_start(int argc, char *argv[]) {
    rt_thread_t thread;
 
    /* 创建TCP服务器线程 */
    thread = rt_thread_create("server", tcp_server_thread_entry, RT_NULL, 2048, 20, 10);
    if (thread != RT_NULL) 
	{
		rt_thread_start(thread );
	}
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值