1@page page_component_network Network Framework
2
3With the popularity of the Internet, people's lives are increasingly dependent on the application of the network. More and more products need to connect to the Internet, and device networking has become a trend. To achieve the connection between the device and the network, you need to follow the TCP/IP protocol, you can run the network protocol stack on the device to connect to the network, or you can use devices (chips with hardware network protocol stack interfaces) to connect to the Internet.
4
5When the device is connected to the network, it is like plugging in the wings. You can use the network to upload data in real time. The user can see the current running status and collected data of the device in a hundred thousand miles, and remotely control the device to complete specific tasks. You can also play online music, make online calls, and act as a LAN storage server through your device.
6
7This chapter will explain the related content of the RT-Thread network framework, and introduce you to the concept, function and usage of the network framework. After reading this chapter, you will be familiar with the concept and implementation principle of the RT-Thread network framework and familiar with  network programming using Socket API.
8
9# TCP/IP Introduction to Network Protocols
10
11TCP/IP is short for Transmission Control Protocol/Internet Protocol. It is not a single protocol, but a general term for a protocol family. It includes IP protocol, ICMP protocol, TCP protocol, and http and ftp, pop3, https protocol, etc., which define how electronic devices connect to the Internet and the standards by which data is transferred between them.
12
13## OSI Reference Model
14
15OSI (Open System Interconnect), which is an open system interconnection. Generally referred to as the OSI reference model, it is a network interconnection model studied by the ISO (International Organization for Standardization) in 1985.  The architecture standard defines a seven-layer framework for the network interconnection (physical layer, data link layer, network layer, transport layer, session layer, presentation layer, and application layer), that is, the ISO open system interconnection reference model. The first to third layers belong to the lower three layers of the OSI Reference Model and are responsible for creating links for network communication connections; the fourth to seventh layers are the upper four layers of the OSI reference model and is responsible for end-to-end data communication. The capabilities of each layer are further detailed in this framework to achieve interconnectivity, interoperability, and application portability in an open system environment.
16
17## TCP/IP Reference Model
18
19The TCP/IP communication protocol uses a four-layer hierarchical structure, and each layer calls the network provided by its next layer to fulfill its own needs. The four layers are:
20
21* **Application layer**: Different types of network applications have different communication rules, so the application layer protocols are various, such as Simple Mail Transfer Protocol (SMTP), File Transfer Protocol (FTP), and network remote access protocol (Telnet).
22* **Transport layer**: In this layer, it provides data transfer services between nodes, such as Transmission Control Protocol (TCP), User Datagram Protocol (UDP), etc. TCP and UDP add data to the data packet and transmit it to the next layer, this layer is responsible for transmitting data and determining that the data has been delivered and received.
23* **Network layer**: responsible for providing basic data packet transfer functions, so that each packet can reach the destination host (but not check whether it is received correctly), such as Internet Protocol (IP).
24* **Network interface layer**: Management of actual network media, defining how to use actual networks (such as Ethernet, Serial Line, etc.) to transmit data.
25
26## Difference between TCP/IP Reference Model and OSI Reference Model
27
28The following figure shows the TCP/IP reference model and the OSI reference model diagram:
29
30![TCP/IP Reference Model and OSI Reference Model](figures/net-osi.png)
31
32Both the OSI reference model and the TCP/IP reference model are hierarchical, based on the concept of a separate protocol stack. The OSI reference model has 7 layers, while the TCP/IP reference model has only 4 layers, that is, the TCP/IP reference model has no presentation layer and session layer, and the data link layer and physical layer are merged into a network interface layer. However, there is a certain correspondence between the two layers. Due to the complexity of the OSI system and the design prior to implementation, many designs are too ideal and not very convenient for software implementation. Therefore, there are not many systems that fully implement the OSI reference model, and the scope of application is limited. The TCP/IP reference model was first implemented in a computer system. It has a stable implementation on UNIX and Windows platforms, and provides a simple and convenient programming interface (API) on which a wide range of applications are developed. The TCP/IP reference model has become the international standard and industry standard for Internet connectivity.
33
34## IP Address
35
36The IP address refers to the Internet Protocol Address (also translated as the Internet Protocol Address) and is a uniform address format that assigns a logical address to each network and each host on the Internet to mask physical address differences provided by  Internet Protocol. The common LAN IP address is 192.168.X.X.
37
38## Subnet Mask
39
40Subnet mask (also called netmask, address mask), which is used to indicate which bits of an IP address identify the subnet where the host is located, and which bits are identified as the bit mask of the host. The subnet mask cannot exist alone, it must be used in conjunction with an IP address. Subnet mask has only one effect, which is to divide an IP address into two parts: network address and host address. The subnet mask is the bit of 1, the IP address is the network address, the subnet mask is the bit of 0, and the IP address is the host address. Taking the IP address 192.168.1.10 and the subnet mask 255.255.255.0 as an example, the first 24 bits of the subnet mask (converting decimal to binary) is 1, so the first 24 bits of the IP address 192.168.1 represent the network address. The remaining 0 is the host address.
41
42## MAC Address
43
44MAC (figures Access Control or Medium Access Control) address, which is translated as media access control, or physical address, hardware address, used to define the location of  network devices. In OSI model, the third layer network Layer is responsible for IP address, the second layer data link layer is responsible for the MAC address. A host will have at least one MAC address.
45
46# Introduction to the Network Framework of RT-Thread
47
48In order to support various network protocol stacks, RT-Thread has developed a **SAL** component, the full name of the **Socket abstraction layer**. RT-Thread can seamlessly access various protocol stacks, including several commonly used TCP/IP protocol stack, such as the LwIP protocol stack commonly used in embedded development and the AT Socket protocol stack component developed by RT-Thread, which complete the conversion of data from the network layer to the transport layer.
49
50The main features of the RT-Thread network framework are as follows:
51
52* Support for standard network sockets BSD Socket API, support for poll/select
53* Abstract, unified multiple network protocol stack interfaces
54* Support various physical network cards, network communication module hardware
55* The resource occupancy of SAL socket abstraction layer component is small: ROM 2.8K and RAM 0.6K.
56
57RT-Thread's network framework adopts a layered design with four layers, each layer has different responsibilities. The following figure shows the RT-Thread network framework structure:
58
59![RT-Thread network framework structure](figures/net-layer.png)
60
61The network framework provides a standard BSD Socket interface to user applications. Developers use the BSD Socket interface to operate without worrying about how the underlying network is implemented, and no need to care which network protocol stack the network data passes through. The socket abstraction layer provides the upper application layer. The interfaces are: `accept`, `connect`, `send`, `recv`, etc.
62
63Below the SAL layer is the protocol stack layer. The main protocol stacks supported in the current network framework are as follows:
64
65* **LwIP** is an open source TCP/IP protocol stack implementation that reduces RAM usage while maintaining the main functionality of the TCP/IP protocol, making the LwIP protocol stack ideal for use in embedded systems.
66* **AT Socket** is a component for modules that support AT instructions. The AT command uses a standard serial port for data transmission and reception, and converts complex device communication methods into simple serial port programming, which greatly simplifies the hardware design and software development costs of the product, which makes almost all network modules such as GPRS, 3G/4G, NB-IoT, Bluetooth, WiFi, GPS and other modules are very convenient to access the RT-Thread network framework, develop network applications through the standard BSD Socket method, greatly simplifying the development of upper-layer applications.
67* **Socket CAN** is a way of programming CAN, it is easy to use and easy to program. By accessing the SAL layer, developers can implement Socket CAN programming on RT-Thread.
68
69Below the protocol stack layer is an abstract device layer that is connected to various network protocol stacks by abstracting hardware devices into Ethernet devices or AT devices.
70
71The bottom layer is a variety of network chips or modules (for example: Ethernet chips with built-in protocol stack such as W5500/CH395, WiFi module with AT command, GPRS module, NB-IoT module, etc.). These hardware modules are the carrier that truly performs the network communication function and is responsible for communicating with various physical networks.
72
73In general, the RT-Thread network framework allows developers to only care about and use the standard BSD Socket network interface for network application development, without concern for the underlying specific network protocol stack type and implementation, greatly improving system compatibility and convenience. Developers have completed the development of network-related applications, and have greatly improved the compatibility of RT-Thread in different areas of the Internet of Things.
74
75In addition, based on the network framework, RT-Thread provides a large number of network software packages, which are various network applications based on the SAL layer, such as **Paho MQTT**, **WebClient**, **cJSON**, **netutils**, etc., which can be obtained from the online package management center. These software packages are web application tools. Using them can greatly simplify the development of network applications and shorten the network application development cycle. At present, there are more than a dozen network software packages. The following table lists some of the network software packages currently supported by RT-Thread, and the number of software packages is still increasing.
76
77| **Package Name** | **Description**                                              |
78| ---------------- | ------------------------------------------------------------ |
79| Paho MQTT        | Based on Eclipse open source Paho MQTT, it has done a lot of functions and performance optimization, such as: increased automatic reconnection after disconnection, pipe model, support for non-blocking API, support for TLS encrypted transmission, etc. |
80| WebClient        | Easy-to-use HTTP client with support for HTTP GET/POST and other common request functions, support for HTTPS, breakpoint retransmission, etc. |
81| mongoose         | Embedded Web server network library, similar to Nginx in the embedded world. Licensing is not friendly enough, business needs to be charged |
82| WebTerminal      | Access Finsh/MSH Shell packages in the browser or on the mobile |
83| cJSON            | Ultra-lightweight JSON parsing library                       |
84| ljson            | Json to struct parsing, output library                       |
85| ezXML            | XML file parsing library, currently does not support parsing XML data |
86| nanopb           | Protocol Buffers format data parsing library, Protocol Buffers format takes up less resources than JSON, XML format resources |
87| GAgent           | Software package for accessing Gizwits Cloud Platform        |
88| Marvell WiFi     | Marvell WiFi driver                                          |
89| Wiced WiFi       | WiFi driver for Wiced interface                              |
90| CoAP             | Porting libcoap's CoAP communication package                 |
91| nopoll           | Ported open source WebSocket communication package           |
92| netutils         | A collection of useful network debugging gadgets, including: ping, TFTP, iperf, NetIO, NTP, Telnet, etc. |
93| OneNet           | Software for accessing China Mobile OneNet Cloud             |
94
95# Network Framework Workflow
96
97Using the RT-Thread network framework, you first need to initialize the SAL, then register various network protocol clusters to ensure that the application can communicate using the socket network socket interface. This section mainly uses LwIP as an example.
98
99## Register the Network Protocol Cluster
100
101First use the `sal_init()` interface to initialize resources such as mutex locks used in the component. The interface looks like this:
102
103```c
104int sal_init(void);
105```
106
107After the SAL is initialized, then use the  the `sal_proto_family_register()` interface to register network protocol cluster, for example, the LwIP network protocol cluster is registered to the SAL. The sample code is as follows:
108
109```c
110static const struct proto_family LwIP_inet_family_ops = {
111    "LwIP",
112    AF_INET,
113    AF_INET,
114    inet_create,
115    LwIP_gethostbyname,
116    LwIP_gethostbyname_r,
117    LwIP_freeaddrinfo,
118    LwIP_getaddrinfo,
119};
120
121int LwIP_inet_init(void)
122{
123    sal_proto_family_register(&LwIP_inet_family_ops);
124
125    return 0;
126}
127```
128
129`AF_INET` stands for IPv4 address, for example 127.0.0.1; `AF` is short for "Address Family" and `INET` is short for "Internet".
130
131The `sal_proto_family_register()` interface is defined as follows:
132
133```
134int sal_proto_family_register(const struct proto_family *pf);
135```
136
137|**Parameters**|**Description**       |
138|----------|------------------|
139| pf       | Protocol cluster structure pointer |
140|**Return**|**——**         |
141| 0        | registration success |
142| -1      | registration failed |
143
144## Network Data Receiving Process
145
146After the LwIP is registered to the SAL, the application can send and receive network data through the network socket interface. In LwIP, several main threads are created, and they are `tcpip` thread, `erx` receiving thread and `etx` sending thread. The network data receiving process is as shown in the following picture. The application receives data by calling the standard socket interface `recv()` with blocking mode. When the Ethernet hardware device receives the network data packet, it stores the packet in the receiving buffer, and then sends an email to notify the `erx` thread that the data arrives through the Ethernet interrupt program. The `erx` thread applies for the `pbuf` memory block according to the received data length and put the data into the pbuf's `payload` data, then send the `pbuf` memory block to the `tcpip` thread via mailbox, and the `tcpip` thread returns the data to the application that is blocking the receiving data.
147
148![Data receiving function call flow chart](figures/net-recv.png)
149
150## Network Data Sending Process
151
152The network data sending process is shown in the figure below. When there is data to send, the application calls the standard network socket interface `send()` to hand the data to the `tcpip` thread. The `tcpip` thread sends a message to wake up the `etx` thread. The `etx` thread first determines if the Ethernet is sending data. If data is not being sent, it will put the data to be sent into the send buffer, and then send the data through the Ethernet device. If data is being sent, the `etx` thread suspends itself until the Ethernet device is idle before sending the data out.
153
154![Data sending function call flow chart](figures/net-send.png)
155
156# Network Socket Programming
157
158The application uses Socket (network socket) interface programming to implement network communication functions. Socket is a set of application program interface (API), which shields the communication details of each protocol, so that the application does not need to pay attention to the protocol itself, directly using the interfaces provide by socket to communicate between different hosts interconnected.
159
160## TCP socket Communication Process
161
162TCP(Tranfer Control Protocol) is a connection-oriented protocol to ensure reliable data transmission. Through the TCP protocol transmission, a sequential error-free data stream is obtained. The TCP-based socket programming flow diagram is shown in the following figure. A connection must be established between the sender and the receiver's two sockets in order to communicate on the basis of the TCP protocol. When a socket (usually a server socket) waits for a connection to be established. Another socket can request a connection. Once the two sockets are connected, they can perform two-way data transmission, and both sides can send or receive data. A TCP connection is a reliable connection that guarantees that packets arrive in order, and if a packet loss occurs, the packet is automatically resent.
163
164For example, TCP is equivalent to calling in life. When you call the other party, you must wait for the other party to answer. Only when the other party answers your call  can he/she establish a connection with you. The two parties can talk and pass information to each other. Of course, the information passed at this time is reliable, because the other party can't hear what you said and can ask you to repeat the content again. When either party on the call wants to end the call, they will bid farewell to the other party and wait until the other party bids farewell to them before they hang up and end the call.
165
166![TCP-based socket programming flow chart](figures/net-tcp.png)
167
168## UDP socket Communication Process
169
170UDP is short for User Datagram Protocol. It is a connectionless protocol. Each datagram is a separate information, including the complete source address and destination address. It is transmitted to the destination on the network in any possible path. Therefore, whether the destination can be reached, the time to reach the destination, and the correctness of the content cannot be guaranteed. The UDP-based socket programming flow is shown in the following figure.
171
172![UDP-based socket programming flow](figures/net-udp.png)
173
174For example, UDP is equivalent to the walkie-talkie communication in life. After you set up the channel, you can directly say the information you want to express. The data is sent out by the walkie-talkie, but you don't know if your message has been received by others. By the way, unless someone else responds to you with a walkie-talkie. So this method is not reliable.
175
176## Create a Socket
177
178Before communicating, the communicating parties first use the `socket()` interface to create a socket, assigning a socket descriptor and its resources based on the specified address family, data type, and protocol. The interface is as follows:
179
180```c
181int socket(int domain, int type, int protocol);
182```
183
184|**Parameters**|**Description**                                       |
185|----------|--------------------------------------------------|
186| domain   | Protocol family                            |
187| type     | Specify the communication type, including values SOCK_STREAM and SOCK_DGRAM. |
188| protocol | Protocol allows to specify a protocol for the socket, which is set to 0 by default. |
189|**Return**|**——**                                         |
190| >=0     | Successful, returns an integer representing the socket descriptor |
191| -1      | Fail                                         |
192
193**Communication types** include SOCK_STREAM and SOCK_DGRAM.
194
195**SOCK_STREAM** indicates connection-oriented TCP data transfer. Data can arrive at another computer without any errors. If it is damaged or lost, it can be resent, but it is relatively slow.
196
197**SOCK_DGRAM** indicates the connectionless UDP data transfer method. The computer only transmits data and does not perform data verification. If the data is damaged during transmission or does not reach another computer, there is no way to remedy it. In other words, if the data is wrong, it is wrong and cannot be retransmitted. Because SOCK_DGRAM does less validation work, it is more efficient than SOCK_STREAM.
198
199The sample code for creating a TCP type socket is as follows:
200
201```c
202 /* Create a socket, type is SOCKET_STREAM,TCP type */
203    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
204    {
205        /* failed to create socket*/
206        rt_kprintf("Socket error\n");
207
208        return;
209    }
210```
211
212## Binding Socket
213
214A binding socket is used to bind a port number and an IP address to a specified socket. When using socket() to create a socket, only the protocol family is given, and no address is assigned. Before the socket receives a connection from another host, it must bind it with an address and port number using bind(). The interface is as follows:
215
216```c
217int bind(int s, const struct sockaddr *name, socklen_t namelen);
218```
219
220|**Parameters**|**Description**                                 |
221|----------|--------------------------------------------|
222| S        | Socket descriptor             |
223| name     | Pointer to the sockaddr structure representing the address to be bound |
224| namelen  | Length of sockaddr structure |
225|**Return**|**——**                                   |
226| 0        | Successful                      |
227| -1      | Fail                                   |
228
229## Establishing a TCP Connection
230
231For server-side programs, after using `bind()` to bind the socket, you also need to use the `listen()` function to make the socket enter the passive listening state, and then call the `accept()` function to respond to the client at any time.
232
233### Listening Socket
234
235The listening socket is used by the TCP server to listen for the specified socket connection. The interface is as follows:
236
237```c
238int listen(int s, int backlog);
239```
240
241|**Parameters**|**Description**                     |
242|----------|--------------------------------|
243| s        | Socket descriptor  |
244| backlog  | Indicates the maximum number of connections that can be waited at a time |
245|**Return**|**——**                       |
246| 0        | Successful                  |
247| -1      | Fail                       |
248
249### Accept the Connection
250
251When the application listens for connections from other clients, the connection must be initialized with the `accept()` function, which creates a new socket for each connection and removes the connection from the listen queue. The interface is as follows:
252
253```c
254int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
255```
256
257|**Parameters**|**Description**                     |
258|----------|--------------------------------|
259| s        | Socket descriptor  |
260| addr     | Client device address information |
261| addrlen  | Client device address structure length |
262|**Return**|**——**                       |
263| >=0     | Successful, return the newly created socket descriptor |
264| -1      | Fail                        |
265
266### Establish Connection
267
268Used by the client to establish a connection with the specified server. The interface is as follows:
269
270```
271int connect(int s, const struct sockaddr *name, socklen_t namelen);
272```
273
274|**Parameters**|**Description**             |
275|----------|------------------------|
276| s        | Socket descriptor |
277| name     | Server address information |
278| namelen  | Server address structure length |
279|**Return**|**——**             |
280| 0        | Successful       |
281| -1      | Fail               |
282
283When the client connects to the server, first set the server address and then use the `connect()` function to connect. The sample code is as follows:
284
285```c
286struct sockaddr_in server_addr;
287/* Initialize the pre-connected server address */
288server_addr.sin_family = AF_INET;
289server_addr.sin_port = htons(port);
290server_addr.sin_addr = *((struct in_addr *)host->h_addr);
291rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
292
293/* Connect to the server */
294if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
295{
296    /* Connection failed */
297    closesocket(sock);
298
299    return;
300}
301```
302
303## Data Transmission
304
305TCP and UDP have different data transmission methods. TCP needs to establish a connection before data transmission, use `send()` function for data transmission, use `recv()` function for data reception, and UDP does not need to establish connection. It uses `sendto()` function sends data and receives data using the `recvfrom()` function.
306
307### TCP Data Transmission
308
309After the TCP connection is established, the data is sent using the `send()` function. The interface is as follows:
310
311```c
312int send(int s, const void *dataptr, size_t size, int flags);
313```
314
315|**Parameters**|**Description**                 |
316|----------|----------------------------|
317| s        | Socket descriptor |
318| dataptr  | The data pointer to send |
319| size     | Length of data sent |
320| flags    | Flag, generally 0 |
321|**Return**|**——**                   |
322| >0      | Successful, return the length of the sent data |
323| <=0     | Failed                 |
324
325### TCP Data Reception
326
327After the TCP connection is established, use `recv()` to receive the data. The interface is as follows:
328
329```c
330int recv(int s, void *mem, size_t len, int flags);
331```
332
333|**Parameters**|**Description**                 |
334|----------|----------------------------|
335| s        | Socket descriptor |
336| mem      | Received data pointer |
337| len      | Received data length |
338| flags    | Flag, generally 0 |
339|**Return**|**Description**                 |
340| >0      | Successful, return the length of the received data |
341| =0       | The destination address has been transferred and the connection is closed |
342| <0      | Fail                    |
343
344### UDP Data transmission
345
346In the case where a connection is not established, you can use the `sendto()` function to send UDP data to the specified destination address, as shown below:
347
348```c
349int sendto(int s, const void *dataptr, size_t size, int flags,
350           const struct sockaddr *to, socklen_t tolen);
351```
352
353|**Parameters**|**Description**                 |
354|----------|----------------------------|
355| s        | Socket descriptor                              |
356| dataptr  | Data pointer sent |
357| size     | Length of data sent |
358| flags    | Flag, generally 0 |
359| to       | Target address structure pointer |
360| tolen    | Target address structure length |
361|**Return**|**——**                   |
362| >0      | Successful, return the length of the sent data |
363| <=0     | Fail                |
364
365### UDP Data Reception
366
367To receive UDP data, use the `recvfrom()` function, and the interface is:
368
369```c
370int recvfrom(int s, void *mem, size_t len, int flags,
371             struct sockaddr *from, socklen_t *fromlen);
372```
373
374|**Parameters**|**Description**                 |
375|----------|----------------------------|
376| s        | Socket descriptor |
377| mem      | Received data pointer                                        |
378| len      | Received data length |
379| flags    | Flag, generally 0 |
380| from     | Receive address structure pointer |
381| fromlen  | Receive address structure length |
382|**Return**|**——**                   |
383| >0      | Successful, return the length of the received data |
384| 0        | The receiving address has been transferred and the connection is closed |
385| <0      | Fail                   |
386
387## Close Network Connection
388
389After the network communication is over, you need to close the network connection. There are two ways to use `closesocket()` and `shutdown()`.
390
391The `closesocket()` interface is used to close an existing socket connection, release the socket resource, clear the socket descriptor from memory, and then the socket could not be used again. The connection and cache associated with the socket are also lost the meaning, the TCP protocol will automatically close the connection. The interface is as follows:
392
393```c
394int closesocket(int s);
395```
396
397|**Parameters**|**Description**   |
398|----------|--------------|
399| s        | Socket descriptor |
400|**Return**|**——**     |
401| 0        | Successful |
402| -1      | Fail     |
403
404Network connections can also be turned off using the `shutdown()` function. The TCP connection is full-duplex. You can use the `shutdown()` function to implement a half-close. It can close the read or write operation of the connection, or both ends, but it does not release the socket resource. The interface is as follows:
405
406```c
407int shutdown(int s, int how);
408```
409
410|**Parameters**|**Description**            |
411|----------|-----------------------------|
412| s        | Socket descriptor        |
413| how      | SHUT_RD closes the receiving end of the connection and no longer receives data. <br />SHUT_WR closes the connected sender and no longer sends data. <br />SHUT_RDWR is closed at both ends. |
414|**Return**|**——**                    |
415| 0        | Successful           |
416| -1      | Fail                    |
417
418# Network Function Configuration
419
420The main functional configuration options of the network framework are shown in the following table, which can be configured according to different functional requirements:
421
422SAL component configuration options:
423
424|**Macro Definition**           |**Value Type**|**Description**         |
425|------------------------|--------------|--------------------|
426| RT_USING_SAL           | Boolean  | Enable SAL |
427| SAL_USING_LWIP         | Boolean | Enable LwIP component |
428| SAL_USING_AT           | Boolean  | Enable the AT component |
429| SAL_USING_POSIX        | Boolean  | Enable POSIX interface                    |
430| SAL_PROTO_FAMILIES_NUM | Integer  | the maximum number of protocol families supported |
431
432LwIP Configuration options:
433
434|**Macro Definition**                |**Value Type**|**Description**           |
435|-----------------------------|--------------|----------------------|
436| RT_USING_LWIP               | Boolean  | Enable  LwIP protocol |
437| RT_USING_LWIP_IPV6          | Boolean  | Enable IPV6 protocol |
438| RT_LWIP_IGMP                | Boolean  | Enable the IGMP protocol |
439| RT_LWIP_ICMP                | Boolean  | Enable the ICMP protocol |
440| RT_LWIP_SNMP                | Boolean  | Enable the SNMP protocol |
441| RT_LWIP_DNS                 | Boolean  | Enable DHCP function |
442| RT_LWIP_DHCP                | Boolean  | Enable DHCP function |
443| IP_SOF_BROADCAST            | Integer  | filtering roadcasting Packets Sended by IP |
444| IP_SOF_BROADCAST_RECV       | Integer  | filtering roadcasting Packets received by IP |
445| RT_LWIP_IPADDR              | String | IP address     |
446| RT_LWIP_GWADDR              | String | Gateway address |
447| RT_LWIP_MSKADDR             | String | Subnet mask |
448| RT_LWIP_UDP                 | Boolean  | Enable UDP protocol |
449| RT_LWIP_TCP                 | Boolean  | Enable TCP protocol |
450| RT_LWIP_RAW                 | Boolean  | Enable RAW API                             |
451| RT_MEMP_NUM_NETCONN         | Integer  | Support Numbers of network links |
452| RT_LWIP_PBUF_NUM            | Integer  | pbuf number of memory blocks |
453| RT_LWIP_RAW_PCB_NUM         | Integer  | Maximum number of connections for RAW |
454| RT_LWIP_UDP_PCB_NUM         | Integer  | Maximum number of connections for UDP |
455| RT_LWIP_TCP_PCB_NUM         | Integer  | Maximum number of connections for TCP |
456| RT_LWIP_TCP_SND_BUF         | Integer  | TCP send buffer size |
457| RT_LWIP_TCP_WND             | Integer  | TCP sliding window size |
458| RT_LWIP_TCPTHREAD_PRIORITY  | Integer  | TCP thread priority |
459| RT_LWIP_TCPTHREAD_MBOX_SIZE | Integer  | TCP thread mailbox size |
460| RT_LWIP_TCPTHREAD_STACKSIZE | Integer  | TCP thread stack size |
461| RT_LWIP_ETHTHREAD_PRIORITY  | Integer  | Receive/send thread's priority |
462| RT_LWIP_ETHTHREAD_STACKSIZE | Integer  | Receive/send thread's stack size |
463| RT_LwIP_ETHTHREAD_MBOX_SIZE | Integer  | Receive/send thread's mailbox size |
464
465# Network Application Example
466
467## View IP Address
468
469In the console, you can use the ifconfig command to check the network status. The IP address is 192.168.12.26, and the FLAGS status is LINK_UP, indicating that the network is configured:
470
471```c
472msh >ifconfig
473network interface: e0 (Default)
474MTU: 1500
475MAC: 00 04 a3 12 34 56
476FLAGS: UP LINK_UP ETHARP BROADCAST IGMP
477ip address: 192.168.12.26
478gw address: 192.168.10.1
479net mask  : 255.255.0.0·
480dns server #0: 192.168.10.1
481dns server #1: 223.5.5.5
482```
483
484## Ping Network Test
485
486Use the ping command for network testing:
487
488```c
489msh />ping rt-thread.org
49060 bytes from 116.62.244.242 icmp_seq=0 ttl=49 time=11 ticks
49160 bytes from 116.62.244.242 icmp_seq=1 ttl=49 time=10 ticks
49260 bytes from 116.62.244.242 icmp_seq=2 ttl=49 time=12 ticks
49360 bytes from 116.62.244.242 icmp_seq=3 ttl=49 time=10 ticks
494msh />ping 192.168.10.12
49560 bytes from 192.168.10.12 icmp_seq=0 ttl=64 time=5 ticks
49660 bytes from 192.168.10.12 icmp_seq=1 ttl=64 time=1 ticks
49760 bytes from 192.168.10.12 icmp_seq=2 ttl=64 time=2 ticks
49860 bytes from 192.168.10.12 icmp_seq=3 ttl=64 time=3 ticks
499msh />
500```
501
502Getting the above output indicates that the connection network is successful!
503
504## TCP Client Example
505
506After the network is successfully connected, you can run the network example, first run the TCP client example. This example will open a TCP server on the PC, open a TCP client on the IoT Board, and both parties will communicate on the network.
507
508In the example project, there is already a TCP client program `tcpclient_sample.c`. The function is to implement a TCP client that can receive and display the information sent from the server. If it receives the information starting with 'q' or 'Q', then exit the program directly and close the TCP client. The program exports the tcpclient command to the FinSH console. The command  format is `tcpclient URL PORT`, where URL is the server address and PORT is the port number. The sample code is as follows:
509
510```c
511/*
512 * Program list: tcp client
513 *
514 * This is a tcp client routine
515 * Export the tcpclient command to MSH
516 * Command call format: tcpclient URL PORT
517 * URL: server address PORT:: port number
518 * Program function: Receive and display the information sent from the server, and receive the information that starts with 'q' or 'Q' to exit the program.
519*/
520
521#include <rtthread.h>
522#include <sys/socket.h> /* To use BSD socket, you need to include the socket.h header file. */
523#include <netdb.h>
524#include <string.h>
525#include <finsh.h>
526
527#define BUFSZ   1024
528
529static const char send_data[] = "This is TCP Client from RT-Thread."; /* Sending used data */
530void tcpclient(int argc, char**argv)
531{
532    int ret;
533    char *recv_data;
534    struct hostent *host;
535    int sock, bytes_received;
536    struct sockaddr_in server_addr;
537    const char *url;
538    int port;
539
540    /* Received less than 3 parameters */
541    if (argc < 3)
542    {
543        rt_kprintf("Usage: tcpclient URL PORT\n");
544        rt_kprintf("Like: tcpclient 192.168.12.44 5000\n");
545        return ;
546    }
547
548    url = argv[1];
549    port = strtoul(argv[2], 0, 10);
550
551    /* Get the host address through the function entry parameter url (if it is a domain name, it will do domain name resolution) */
552    host = gethostbyname(url);
553
554    /* Allocate buffers for storing received data */
555    recv_data = rt_malloc(BUFSZ);
556    if (recv_data == RT_NULL)
557    {
558        rt_kprintf("No memory\n");
559        return;
560    }
561
562    /* Create a socket of type SOCKET_STREAM, TCP type */
563    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
564    {
565        /* Failed to create socket */
566        rt_kprintf("Socket error\n");
567
568        /* Release receive buffer */
569        rt_free(recv_data);
570        return;
571    }
572
573    /* Initialize the pre-connected server address */
574    server_addr.sin_family = AF_INET;
575    server_addr.sin_port = htons(port);
576    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
577    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
578
579    /* Connect to the server */
580    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
581    {
582        /* Connection failed */
583        rt_kprintf("Connect fail!\n");
584        closesocket(sock);
585
586        /* Release receive buffer */
587        rt_free(recv_data);
588        return;
589    }
590
591    while (1)
592    {
593        /* Receive maximum BUFSZ-1 byte data from a sock connection */
594        bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
595        if (bytes_received < 0)
596        {
597            /* Receive failed, close this connection */
598            closesocket(sock);
599            rt_kprintf("\nreceived error,close the socket.\r\n");
600
601            /* Release receive buffer */
602            rt_free(recv_data);
603            break;
604        }
605        else if (bytes_received == 0)
606        {
607            /* Print the recv function returns a warning message with a value of 0 */
608            rt_kprintf("\nReceived warning,recv function returns 0.\r\n");
609
610            continue;
611        }
612
613        /* Received data, clear the end */
614        recv_data[bytes_received] = '\0';
615
616        if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0)
617        {
618            /* If the initial letter is q or Q, close this connection */
619            closesocket(sock);
620            rt_kprintf("\n got a'q'or'Q',close the socket.\r\n");
621
622            /* Release receive buffer */
623            rt_free(recv_data);
624            break;
625        }
626        else
627        {
628            /* Display the received data at the control terminal */
629            rt_kprintf("\nReceived data = %s", recv_data);
630        }
631
632        /* Send data to sock connection */
633        ret = send(sock, send_data, strlen(send_data), 0);
634        if (ret < 0)
635        {
636            /* Receive failed, close this connection */
637            closesocket(sock);
638            rt_kprintf("\nsend error,close the socket.\r\n");
639
640            rt_free(recv_data);
641            break;
642        }
643        else if (ret == 0)
644        {
645            /* Print the send function returns a warning message with a value of 0 */
646            rt_kprintf("\n Send warning,send function returns 0.\r\n");
647        }
648    }
649    return;
650}
651MSH_CMD_EXPORT(tcpclient, a tcp client sample);
652```
653
654When running the example, first open a network debugging assistant on your computer and open a TCP server. Select the protocol type as TCP
655Server, fill in the local IP address and port 5000, as shown below.
656
657![Network debugging tool interface](figures/net-tcp-s.png)
658
659Then start the TCP client to connect to the TCP server by entering the following command in the FinSH console:
660
661```C
662msh />tcpclient 192.168.12.45 5000  // Input according to actual situation
663Connect successful
664```
665
666When the console outputs the log message "Connect successful", it indicates that the TCP connection was successfully established. Next, you can perform data communication. In the network debugging tool window, send Hello RT-Thread!, which means that a data is sent from the TCP server to the TCP client, as shown in the following figure:
667
668![网络调试工具界面](figures/net-hello.png)
669
670After receiving the data on the FinSH console, the corresponding log information will be output, you can see:
671
672```c
673msh >tcpclient 192.168.12.130 5000
674Connect successful
675Received data = hello world
676Received data = hello world
677Received data = hello world
678Received data = hello world
679Received data = hello world
680 got a 'q' or 'Q',close the socket.
681msh >
682```
683
684The above information indicates that the TCP client received 5 "hello world" data sent from the server. Finally, the exit command 'q' was received from the TCP server, and the TCP client program exited the operation and returned to the FinSH console.
685
686## UDP Client Example
687
688This is an example of a UDP client. This example will open a UDP server on the PC and open a UDP client on the IoT Board for network communication. A UDP client program has been implemented in the sample project. The function is to send data to the server. The sample code is as follows:
689
690```c
691/*
692 * Program list: udp client
693 *
694 * This is a udp client routine
695 * Export the udpclient command to the msh
696 * Command call format: udpclient URL PORT [COUNT = 10]
697 * URL: Server Address PORT: Port Number COUNT: Optional Parameter Default is 10
698 * Program function: send COUNT datas to the remote end of the service
699*/
700
701#include <rtthread.h>
702#include <sys/socket.h> /* To use BSD socket, you need to include the sockets.h header file. */
703#include <netdb.h>
704#include <string.h>
705#include <finsh.h>
706
707const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* data */
708
709void udpclient(int argc, char**argv)
710{
711    int sock, port, count;
712    struct hostent *host;
713    struct sockaddr_in server_addr;
714    const char *url;
715
716    /* Received less than 3 parameters */
717    if (argc < 3)
718    {
719        rt_kprintf("Usage: udpclient URL PORT [COUNT = 10]\n");
720        rt_kprintf("Like: udpclient 192.168.12.44 5000\n");
721        return ;
722    }
723
724    url = argv[1];
725    port = strtoul(argv[2], 0, 10);
726
727    if (argc> 3)
728        count = strtoul(argv[3], 0, 10);
729    else
730        count = 10;
731
732    /* Get the host address through the function entry parameter url (if it is a domain name, it will do domain name resolution) */
733    host = (struct hostent *) gethostbyname(url);
734
735    /* Create a socket of type SOCK_DGRAM, UDP type */
736    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
737    {
738        rt_kprintf("Socket error\n");
739        return;
740    }
741
742    /* Initialize the pre-connected server address */
743    server_addr.sin_family = AF_INET;
744    server_addr.sin_port = htons(port);
745    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
746    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
747
748    /* Send count data in total */
749    while (count)
750    {
751        /* Send data to the remote end of the service */
752        sendto(sock, send_data, strlen(send_data), 0,
753               (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
754
755        /* Thread sleep for a while */
756        rt_thread_delay(50);
757
758        /* Count value minus one */
759        count --;
760    }
761
762    /* Turn off this socket */
763    closesocket(sock);
764}
765```
766
767When running the example, first open a network debugging assistant on your computer and open a UDP server. Select the protocol type as UDP and fill in the local IP address and port 5000, as shown in the figure below.
768
769![网络调试工具界面](figures/net-udp-server.png)
770
771Then you can enter the following command in the FinSH console to send data to the UDP server.
772
773```c
774msh />udpclient 192.168.12.45 1001          // Need to enter according to the real situation
775```
776
777The server will receive 10 messages from This is UDP Client from RT-Thread., as shown below:
778
779![网络调试工具界面](figures/net-udp-client.png)
780