在sal的基础上,tcp server的操作和pc端的流程基本一致,这里做一个小demo,server监听5000端口,向发起连接的client对象发送一个字符串,然后阻塞接收client发回的数据,再断开连接,等待下一个连接请求。
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-02-20 ShineRoyal the first version
*/
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
static const char *send_data = "hello RT-Thread\n";
void tcpserver(int argc, char **argv)
{
int sock_listen, sock_connect, port;
struct hostent *host;
struct sockaddr_in listen_addr;
struct sockaddr_in connect_addr;
const char *url;
url = "192.168.1.42"; //localhost ip
port = 5000;
/* 通过函数入口参数 url 获得 host 地址(如果是域名,会做域名解析) */
host = (struct hostent *) gethostbyname(url);
/* 创建一个 socket,类型是 SOCK_DGRAM,UDP 类型 */
/*SOCK_STREAM => TCP*/
if ((sock_listen = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
return;
}
/* 初始化预连接的服务端地址 */
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = htons(port);
listen_addr.sin_addr = *((struct in_addr *) host->h_addr);
rt_memset(&(listen_addr.sin_zero), 0, sizeof(listen_addr.sin_zero));
if (bind(sock_listen, (struct sockaddr * )&listen_addr, sizeof(struct sockaddr)) < 0)
{
rt_kprintf("Bind fail!\n");
goto __exit;
}
listen(sock_listen, 10);
while (1)
{
int sin_size = sizeof(struct sockaddr_in);
sock_connect = accept(sock_listen, (struct sockaddr* )&connect_addr, &sin_size);
/* 发送数据到服务远端 */
send(sock_connect, send_data, strlen(send_data), 0);
/* 线程休眠一段时间 */
rt_thread_delay(50);
char str[100];
memset(str, 0, sizeof(str));
recv(sock_connect, str, sizeof(str), 0);
rt_kprintf("%s:%d=>%s\n", inet_ntoa(connect_addr.sin_addr), ntohs(connect_addr.sin_port), str);
closesocket(sock_connect);
}
__exit:
/* 关闭这个 socket */
closesocket(sock_listen);
}
MSH_CMD_EXPORT(tcpserver, tcpserver);