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 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 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 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 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 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 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 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 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 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 780