• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  Copyright (C) 2024 HiHope Open Source Organization .
3  Licensed under the Apache License, Version 2.0 (the "License");
4  you may not use this file except in compliance with the License.
5  You may obtain a copy of the License at
6 
7      http://www.apache.org/licenses/LICENSE-2.0
8 
9  Unless required by applicable law or agreed to in writing, software
10  distributed under the License is distributed on an "AS IS" BASIS,
11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  See the License for the specific language governing permissions and
13  limitations under the License.
14  */
15 
16 
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stddef.h>
20 #include <errno.h>
21 #include <string.h>
22 #include "lwip/sockets.h"
23 #include "oled_ssd1306.h"
24 
25 static char send_data[10] = "test_data";
26 static char recv_data[100] = "";
27 static char display_data[11] = "";
28 
29 /*TCP服务端测试函数*/
TcpServerTest(unsigned short port)30 void TcpServerTest(unsigned short port)
31 {
32     ssize_t ret = 0;
33     int c = 1;
34     // 最大等待队列长度
35     int backlog = 1;
36 
37     // 创建一个TCP Socket
38     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
39 
40     int connfd = -1;
41 
42     // 客户端的IP地址和端口号
43     struct sockaddr_in clientAddr = {0};
44 
45     // clientAddr的长度
46     socklen_t clientAddrLen = sizeof(clientAddr);
47 
48     // 服务端的地址信息
49     struct sockaddr_in serverAddr = {0};
50 
51     /* 配置服务端的信息 */
52 
53     serverAddr.sin_family = AF_INET;//使用IPv4协议
54 
55     serverAddr.sin_port = htons(port);//端口号,从主机字节序转为网络字节序
56 
57     // 允许任意主机接入
58     serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
59 
60     // 将sockfd和本服务器IP、端口号绑定
61     ret = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
62 
63     if (ret < 0) {
64         // 绑定失败
65         printf("bind port failed, %ld!\r\n", ret);
66         OledShowString(0, 2,"                ", FONT6x8);
67         OledShowString(0, 2,"bind port failed", FONT6x8);
68         lwip_close(sockfd);
69 
70 
71     }
72 
73     // 绑定成功
74     printf("bind to port %d success!\r\n", port);
75 
76     // OLED显示端口号
77     OledShowString(0, 1,"                 ", FONT6x8);
78     OledShowString(0, 1,"serverPort:", FONT6x8);
79     OledShowString(0, 2,"                 ", FONT6x8);
80     char strPort[5] = {0};
81     snprintf(strPort, sizeof(strPort), "%d", port);
82     OledShowString(90, 1,strPort, FONT6x8);
83 
84 
85     // 开始监听,最大等待队列长度为backlog
86     // 使用listen接口将sockfd设置为监听模式,在指定的IP和端口上监听客户端发起的连接请求。
87     ret = listen(sockfd, backlog);
88 
89     // 检查接口返回值,小于0表示监听失败
90     if (ret < 0) {
91         // 监听失败
92         printf("listen fail!\r\n");
93         lwip_close(sockfd);
94     }
95 
96     // 监听成功
97     printf("listen with %d backlog success!\r\n", backlog);
98 
99 
100     /* 使用accept接口阻塞式等待客户端连接,创建一个新socket与客户端建立连接。
101     */
102     connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen);
103 
104     if (connfd < 0) {
105         // 建立连接失败
106         printf("accept failed, %d, %d\r\n", connfd, errno);
107         lwip_close(sockfd);
108     }
109 
110     // 建立连接成功
111     printf("accept success, connfd = %d!\r\n", connfd);
112     printf("client addr info: host = %s, port = %d\r\n",
113     inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
114 
115     // OLED显示客户端IP地址
116     OledShowString(0, 3,"udp client ip:", FONT6x8);
117     OledShowString(0, 4,inet_ntoa(clientAddr.sin_addr), FONT6x8);
118 
119     // 发送数据
120     ret = send(connfd, send_data, strlen(send_data), 0);
121 
122     // 发送失败
123     if (ret < 0) {
124         printf("send response failed, %ld!\r\n", ret);
125     }
126 
127     // 发送成功,输出日志,OLED显示发送的数据
128     printf("send response{%s} to client done!\r\n", send_data);
129     while (c)
130     {
131         memset(display_data,0,strlen(display_data));
132         memset(recv_data,0,strlen(recv_data));
133         // 接收收据
134         ret = recv(connfd, recv_data, sizeof(recv_data), 0);
135 
136         // 接收失败或对方的通信端关闭
137         if (ret <= 0) {
138             printf(" recv_data failed or done, %ld!\r\n", ret);
139         }
140 
141         // 接收成功,输出日志,OLED显示收到的收据,最多显示10个字符
142         printf(" recv_data{%s} from client!\r\n", recv_data);
143         OledShowString(0, 7,"recv:", FONT6x8);
144         OledShowString(40, 7,"          ", FONT6x8);
145 
146 
147         memcpy(display_data,recv_data,10);
148         display_data[11] = '\0';
149 
150         OledShowString(40, 7,display_data, FONT6x8);
151         osDelay(100);
152 
153     }
154 
155 
156 
157     //关闭监听socket
158     //lwip_close(sockfd);
159     //关闭连接
160     //lwip_close(connfd);
161 
162 
163 }
164