Files
luban-lite/bsp/examples/test-lwip/test-udp/test_udp_socket.c
刘可亮 11c97ef399 v1.2.1
2025-07-22 11:15:46 +08:00

272 lines
8.0 KiB
C

/*
* Copyright (c) 2025, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: lv.wu@artinchip.com
*/
#include "rtconfig.h"
#ifdef KERNEL_RTTHREAD
#include <rtthread.h>
#endif
#include <stdio.h>
#include "sys/socket.h"
#include "aic_osal.h"
#define UNICAST_SERVER_PORT 8080
#define MUTICAST_SERVER_PORT 8081
#define BOARDCAST_SERVER_PORT 8082
#define UDP_RECV_BUF_SIZE 4096
void udp_test_unicast_thread(void *para)
{
int ret_val;
int socket_fd;
struct sockaddr_in srv_sockaddr;
struct sockaddr_in cln_sockaddr = { 0 };
char *udp_recv_buf;
size_t length = UDP_RECV_BUF_SIZE;
socklen_t fromlen = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
printf("socket alloc error!\n");
return;
}
udp_recv_buf = malloc(UDP_RECV_BUF_SIZE);
if (!udp_recv_buf) {
closesocket(socket_fd);
printf("unicast buff malloc error\n");
return;
}
srv_sockaddr.sin_family = AF_INET;
srv_sockaddr.sin_len = sizeof(struct sockaddr_in);
srv_sockaddr.sin_port = htons(UNICAST_SERVER_PORT);
srv_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret_val = bind(socket_fd, (void *)&srv_sockaddr, sizeof(struct sockaddr_in));
if (ret_val) {
printf("boardcast bind error, maybe has be testing?\n");
goto exit;
}
printf("UDP unicast test start, port : 0x%02x\n", UNICAST_SERVER_PORT);
while (1) {
length = recvfrom(socket_fd, udp_recv_buf, UDP_RECV_BUF_SIZE, 0, (void *)&cln_sockaddr,
&fromlen);
if (length > 0) {
printf("UDP recv data! From:\n");
printf("IP: %s\nPort: %d\n", inet_ntoa(cln_sockaddr.sin_addr),
ntohs(cln_sockaddr.sin_port));
ret_val = sendto(socket_fd, udp_recv_buf, length, 0, (void *)&cln_sockaddr, fromlen);
if (ret_val < 0) {
printf("UDP send error!\n");
goto exit;
}
} else {
printf("recv error\n");
goto exit;
}
}
exit:
closesocket(socket_fd);
free(udp_recv_buf);
}
void udp_test_muticast_thread(void *para)
{
static const char muticase_ip[8][16] = {
"239.26.1.2", "239.26.1.3", "239.26.1.4", "239.26.1.5",
"239.26.1.6", "239.26.1.7", "239.26.1.8", "239.26.1.9",
};
static int ip_index = 0;
int ret_val;
int socket_fd;
struct sockaddr_in srv_sockaddr;
struct sockaddr_in cln_sockaddr = { 0 };
size_t length = UDP_RECV_BUF_SIZE;
socklen_t fromlen = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
printf("muticast socket alloc error!\n");
return;
}
char *udp_recv_buf;
udp_recv_buf = malloc(UDP_RECV_BUF_SIZE);
if (!udp_recv_buf) {
closesocket(socket_fd);
printf("unicast buff malloc error\n");
return;
}
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(muticase_ip[0]);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
checkout_memship:
ret_val = setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
if (ret_val != ERR_OK) {
printf("Join muticast group: %s error!\n", inet_ntoa(mreq.imr_multiaddr.s_addr));
goto exit;
}
printf("Join muticast group: %s sucess!\n", inet_ntoa(mreq.imr_multiaddr.s_addr));
srv_sockaddr.sin_family = AF_INET;
srv_sockaddr.sin_len = sizeof(struct sockaddr_in);
srv_sockaddr.sin_port = htons(MUTICAST_SERVER_PORT);
srv_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret_val = bind(socket_fd, (void *)&srv_sockaddr, sizeof(struct sockaddr_in));
if (ret_val) {
printf("boardcast bind error, maybe has be testing?\n");
goto exit;
}
printf("UDP muticast test start, port : 0x%02x\n", MUTICAST_SERVER_PORT);
while (1) {
length = recvfrom(socket_fd, udp_recv_buf, UDP_RECV_BUF_SIZE, 0, (void *)&cln_sockaddr,
&fromlen);
if (length > 0) {
printf("UDP recv data! From:\n");
printf("IP: %s\nPort: %d\n", inet_ntoa(cln_sockaddr.sin_addr),
ntohs(cln_sockaddr.sin_port));
ret_val = sendto(socket_fd, udp_recv_buf, length, 0, (void *)&cln_sockaddr, fromlen);
if (ret_val < 0) {
printf("muticast UDP send error!\n");
goto exit;
}
ret_val = setsockopt(socket_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq,
sizeof(struct ip_mreq));
if (ret_val != ERR_OK) {
printf("Drop muticast group: %s error!\n", muticase_ip[ip_index]);
goto exit;
}
printf("Drop muticast group: %s sucess!\n", muticase_ip[ip_index]);
ip_index++;
ip_index %= 7;
mreq.imr_multiaddr.s_addr = inet_addr(muticase_ip[ip_index]);
goto checkout_memship;
} else {
printf("muticast recv error\n");
goto exit;
}
}
exit:
closesocket(socket_fd);
free(udp_recv_buf);
}
void udp_test_boardcast_thread(void *para)
{
int ret_val;
int socket_fd;
struct sockaddr_in srv_sockaddr;
struct sockaddr_in cln_sockaddr = { 0 };
size_t length = UDP_RECV_BUF_SIZE;
socklen_t fromlen = sizeof(struct sockaddr_in);
int optval = 1;
int ipaddr;
struct sockaddr_in boardcast_sockaddr = { 0 };
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
printf("socket alloc error!\n");
return;
}
ret_val = setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
if (ret_val != ERR_OK) {
closesocket(socket_fd);
printf("Socket broadcast function set error!\n");
return;
}
char *udp_recv_buf;
udp_recv_buf = malloc(UDP_RECV_BUF_SIZE);
if (!udp_recv_buf) {
closesocket(socket_fd);
printf("unicast buff malloc error\n");
return;
}
inet_aton("255.255.255.255", &ipaddr);
boardcast_sockaddr.sin_family = AF_INET;
boardcast_sockaddr.sin_addr.s_addr = ipaddr;
boardcast_sockaddr.sin_len = sizeof(struct sockaddr_in);
boardcast_sockaddr.sin_port = htons(8080);
srv_sockaddr.sin_family = AF_INET;
srv_sockaddr.sin_len = sizeof(struct sockaddr_in);
srv_sockaddr.sin_port = htons(BOARDCAST_SERVER_PORT);
srv_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret_val = bind(socket_fd, (void *)&srv_sockaddr, sizeof(struct sockaddr_in));
if (ret_val) {
printf("boardcast bind error, maybe has be testing?\n");
goto exit;
}
printf("UDP boardcast test start, src port : 0x%02x\n remote port : 8080",
BOARDCAST_SERVER_PORT);
while (1) {
length = recvfrom(socket_fd, udp_recv_buf, UDP_RECV_BUF_SIZE, 0, (void *)&cln_sockaddr,
&fromlen);
if (length > 0) {
printf("UDP recv data! From:\n");
printf("IP: %s\nPort: %d\n", inet_ntoa(cln_sockaddr.sin_addr),
ntohs(cln_sockaddr.sin_port));
} else {
printf("recv error\n");
goto exit;
}
ret_val = sendto(socket_fd, udp_recv_buf, length, 0, (void *)&boardcast_sockaddr,
sizeof(struct sockaddr_in));
if (ret_val < 0) {
printf("boardcast send error\n");
goto exit;
}
}
exit:
closesocket(socket_fd);
free(udp_recv_buf);
}
int cmd_test_udp(int argc, char *argv[])
{
static int init_flag = 0;
if (init_flag) {
printf("Failed: Only start once\n");
return -1;
}
init_flag++;
aicos_thread_create("udp unicast echo back", 4096, 22, udp_test_unicast_thread, NULL);
aicos_thread_create("udp boardcast echo back", 4096, 22, udp_test_boardcast_thread, NULL);
aicos_thread_create("udp muticast echo back", 4096, 22, udp_test_muticast_thread, NULL);
return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_test_udp, test_udp, udp unicast / muticast / boardcast ehco back);