1、accept函数连接到不同客户端的返回值,对应不同客户端的地址
2、利用1中得到的客户端地址作为线程创建时的参数值client_addr,在为与客户端进行数据通信时,client_addr作为recv函数的参数1.
总结,要想同时和多个客户端进行通信,recv函数得知道是那个客户端;还得建立数据通信的线程。
野火F429+RT-Thread TCP服务器连接多客户端同时通信实现方法_通信服务器rtthread-优快云博客
#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 );
}
}