---
title: "STM Lesson 93. LAN. W5500. HTTP Server. Sockets. Part 1"
url: "https://maker.wiznet.io/teddy/projects/stm-lesson-93-lan-w5500-http-server-sockets-part-1/"
markdown_url: "https://maker.wiznet.io/teddy/projects/stm-lesson-93-lan-w5500-http-server-sockets-part-1/md"
type: "UCC: User Created Content"
author: "Narod stream"
author_url: "https://narodstream.ru/stm-urok-93-lan-w5500-http-server-sokety-chast-1/"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Narod stream"
original_url: "https://narodstream.ru/stm-urok-93-lan-w5500-http-server-sokety-chast-1/"
published: "2023-08-02"
language: "en"
likes: 0
views: 376
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# STM Lesson 93. LAN. W5500. HTTP Server. Sockets. Part 1

> STM Lesson 93. LAN. W5500. HTTP Server. Sockets. Part 1

Original author: Narod stream (source: https://narodstream.ru/stm-urok-93-lan-w5500-http-server-sokety-chast-1/)

## Article

## **LAN. W5500. HTTP Server. Sockets**

Today we are for our module **W5500** try to organize sockets.

— sockets are virtual connections that are used to organize multiple TCP connections operating simultaneously.

That is, if the client with the server wants to create another connection without closing the already created one, then a socket will be used for this. In other words, if we want up to 8 unexploded connections to exist simultaneously between the client and the server, then we must organize 8 sockets. This is necessary for the fact that sometimes many programs create for faster transmission of several simultaneous connections. And, for example, the FTP protocol generally uses 2 open connections. One — for commands and control, and the other — for data transfer.

Therefore, we need to somehow ensure this.

And for this, our chip offers us a ready-made hardware approach. When we met her in [**lesson 91**](https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-1/), we saw that there are two types of registers in it. as well as memory. Designed for general use, that is, independent of any connection, as well as registers and memory for sockets, which are each responsible for their connection. We initialized, and subsequently used only one of them. And today we will try to use others.

To somehow deal with all this, let's create a project from the project [**lesson 91**](https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-1/)** W5500_HTTPS** and call him **W5500_HTTPS_SOCKETS**.

Launch our project at Cube MX.

Let's go to Configuration and in the FATFS parameters we will change the number of simultaneously opened files to "8"

![image07](https://narodstream.ru/wp-content/uploads/2017/09/image07-1.png)

We will also make some adjustments to the SDIO periphery settings. We will set a divider there **2**, so that the controller does not move when copying large volumes of information through this bus

![Image06](https://narodstream.ru/wp-content/uploads/2017/09/Image06-1.png)

If you stand on the line with the divider, then below we will see how the frequency of operation of the SDIO tire is calculated. That is, if we leave the divider by default in **0**, then we get the frequency according to the formula. That is, if we have 48 megahertz tire tacting ( can no longer ), then the real frequency of the tire will be 24, if we install the divider in **eleven**, then we get a frequency of 18 megahertz. We set up a divider **2**, therefore, the frequency of operation of the tire will be 12 megahertz.

In the settings, just in case, increase the size of the stack and heaps four times, since there will be many connections, there will also be many structures and variables, so it may be standard and not enough. Although I tested — everything was enough. But few pages will come across in the future, and somehow 8 connections did not open at once

![Image00](https://narodstream.ru/wp-content/uploads/2017/09/Image00-1.png)

Save changes, generate a project, open it in Keil, connect our libraries **net.c**, **httpd.c** and **w5500.c**, adjust the programmer to the car cutter, set the optimization level 1 and try to assemble.

If everything is going well, then we will begin to think how we can organize work with sockets.

Add to file **httpd.h** prototypes of two functions ( for some reason they were not there, but nevertheless everything worked )

`void``http_request(``void``);`

`**void**``** tcp_send_http_middle(**``**void**``**);**`

`**void**``** tcp_send_http_last(**``**void**``**);**`

`//--------------------------------------------------`

Let's go to the file **w5500.c** and write in it the function of initializing the port in the socket after the function **w5500_readSockBuf**

`**//-----------------------------------------------**`

`**void**``** SetSockPort(**``**uint8_t**``** sock_num, **``**uint16_t**``** port)**`

`**{**`

`** uint8_t**``** opcode;**`

`** opcode = (((sock_num<<2)|BSB_S0)<<3)|OM_FDM1;**`

`** w5500_writeReg(opcode, Sn_PORT0,port>>8);**`

`** w5500_writeReg(opcode, Sn_PORT1,port);**`

`**}**`

`**//-----------------------------------------------**`

We did such an action in initialization, so there is nothing to explain here. We just need a function now, since this action is performed for each socket and it is not a fact that they will have the same ports.

Let's move to the function of initializing the chip to a file **w5500.c** and remove this section of code from it

`~~//Настраиваем сокет 0~~`

`~~opcode = (BSB_S0<<3)|OM_FDM1;~~`

`~~w5500_writeReg(opcode, Sn_PORT0,local_port>>8);~~`

`~~w5500_writeReg(opcode, Sn_PORT1,local_port);~~`

`~~//инициализируем активный сокет~~`

`~~tcpprop.cur_sock = 0;~~`

Instead of all this, insert the following code

`**//Настраиваем сокеты**`

`**SetSockPort(0, local_port);**`

So far, we are also working only with zero socket, but already more universally. We need to achieve the operability of one socket so far, but already with emphasis on its operational change at any moment.

We also remove this line from the initialization

`//Посмотрим статусы`

`~~opcode = (BSB_S0<<3)|OM_FDM1;~~`

And then we’ll fix the code a little, calling a higher-level function

`//Посмотрим статусы`

`**dtt = GetSocketStatus(0);**`

`**sprintf(str1,**``**"First Status Sn%d: 0x%02X\r\n"**``**,0,dtt);**`

`HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);`

We collect the code and check the initialization performance

![Image01](https://narodstream.ru/wp-content/uploads/2017/09/Image01-1.png)

Everything is working.

Add the input argument of the socket number to the package reception function

`void``w5500_packetReceive(**uint8_t sn**)`

We also do not forget about the prototype.

We also pass the parameter in calling this function in a file **net.c**

`w5500_packetReceive(**0**);`

Let's go back to the file **w5500** and in function **w5500_packetReceive** replace line **tcpprop.cur_sock** on **sn**. Since this line is found only in this function, you can use the replacement procedure, calling it the same as the search procedure with a key combination **Ctrl + F**.

We will also change the called parameter where we measure the size of the package that comes. Also there we will fix the display in the terminal program. First, we will also display the socket number there, and display only if it is not empty, that is, move the display below the exit in the case of a zero package

`if``(httpsockprop[sn].data_stat == DATA_COMPLETED)`

`{`

`len = GetSizeRX(**sn**);`

`//Если пришел пустой пакет, то уходим из функции`

`if``(!len) ``return``;`

`//Отобразим размер принятых данных`

`sprintf(str1,``"**S%d **len buf:0x%04X\r\n"``,**sn,**len);`

`HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);`

`//здесь обмениваемся информацией: на запрос документа от клиента отправляем ему запрошенный документ`

The display of the pointer on the data in the buffer can be deleted

`~~sprintf(str1,~~``~~"Sn_RX_RD:0x%04X\r\n"~~``~~,point);~~`

`~~HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);~~`

Also towards the end of this function, display the closed socket number in the terminal

`if``(httpsockprop[sn].prt_tp == PRT_TCP_HTTP)`

`{`

`tcp_send_http_last(sn);`

`DisconnectSocket(sn); ``//Разъединяемся`

`SocketClosedWait(sn);`

`** sprintf(str1,**``**"S%d closed\r\n"**``**,sn);**`

`** HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

Let's go to the file **httpd.c** and also insert a similar input parameter into the void function **http_request**, as well as in her prototype in the title file

`void``http_request(**uint8_t sn**)`

Let's go back to the file **w5500.c** and add the option to call this function to the package acceptance function

`http_request(**sn**);`

Let's go to the file again **httpd.c** and we will also add a similar parameter to all the functions of sending buffers, and to which of them there are prototypes, then there too

`void``tcp_send_http_one(``**uint8_t**``** sn**)`

`void``tcp_send_http_first(``**uint8_t**``** sn**)`

`void``tcp_send_http_middle(``**uint8_t**``** sn**)`

`void``tcp_send_http_last(**uint8_t sn**)`

Also in all function data calls in files **httpd.c** and **w5500.c** also add an argument

`tcp_send_http_one(**sn**);`

`tcp_send_http_first(**sn**);`

`tcp_send_http_middle(**sn**);`

`tcp_send_http_last(**sn**);`

In file **httpd.c** now also replace the occurrence **tcpprop.cur_sock** on **sn**.

I got 109 replacements.

In the functions tcp_send_http_first and tcp_send_http_last, we remove the output to the terminal program of the fact of installing the pointer in the file

`~~sprintf(str1,~~``~~"f_lseek: %d\r\n"~~``~~,result);~~`

`~~HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);~~`

And this is also in the file **w5500.c**

`~~HAL_UART_Transmit(&huart2,(uint8_t*)~~``~~"HTTP\r\n"~~``~~,6,0x1000);~~`

Structure **tcp_prop** we can now delete from the w5500.h file, as well as delete ads of all variables of its type.

In theory, we are no longer tied to zero socket as much as it was before.

First, check the performance on the zero socket, collecting the code, stitching the controller and requesting any document in the browser.

If everything works, then we will try to change the zero socket to the third.

For this we have enough in the files **net.c** and **w5500.c** change the called parameter in the following lines

net: c:

`w5500_packetReceive(**3**);`

**w5500.c**:

`//Настраиваем сокеты`

`SetSockPort(**3**, local_port);`

`//Открываем сокет`

`OpenSocket(**3**,Mode_TCP);`

`SocketInitWait(**3**);`

`//Начинаем слушать сокет`

`ListenSocket(**3**);`

`SocketListenWait(**3**);`

`HAL_Delay(500);`

`//Посмотрим статусы`

`dtt = GetSocketStatus(**3**);`

`sprintf(str1,``"First Status Sn%d: 0x%02X\r\n"``,**3**,dtt);`

We will also check the work after installation as a work socket 3.

If everything works well, then we just need to use a few sockets at once. It will also be very easy.

To do this, create a local variable in the initialization function in the file **w5500.c**

`void``w5500_ini(``void``)`

`{`

`** uint8_t**``** i;**`

`uint8_t``dtt=0;`

And rebuild a little code at the end of the function

`w5500_writeReg(opcode, SIPR3,ipaddr[3]);`

`//Настраиваем сокеты`

`** for**``**(i=3;i<8;i++)**`

`** {**`

`SetSockPort(**i**, local_port);`

`//Открываем сокет`

`OpenSocket(**i**,Mode_TCP);`

`SocketInitWait(**i**);`

`//Начинаем слушать сокет`

`ListenSocket(**i**);`

`SocketListenWait(**i**);`

`** }**`

`HAL_Delay(500);`

`//Посмотрим статусы`

`** for**``**(i=3;i<8;i++)**`

`** {**`

`dtt = GetSocketStatus(**i**);`

`sprintf(str1,``"First Status Sn%d: 0x%02X\r\n"``,**i**,dtt);`

`HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);`

`** }**`

`}`

That is, we initialized 6 sockets under the numbers 3-7.

It also remains in the net.c file to also correct the call function of receiving and processing packages, making it also in the loop

`void``packet_receive(``void``)`

`{`

`** uint8_t**``** i;**`

`** for**``**(i=3;i<8;i++)**`

`** {**`

`w5500_packetReceive(**i**);`

`** }**`

`}`

Also in the file **httpd.c** fix the number of elements in the global array

`http_sock_prop_ptr httpsockprop[**8**];`

We will do the same in the file **w5500.c**

`extern``http_sock_prop_ptr httpsockprop[**8**];`

All this is very good, but there is another interesting ambush. I often forget about her.

We transfer files, sockets work in turn, and we have one variable for the file, and there must be our own for each file. That is, each socket works with its own file, and this happens simultaneously when other sockets work with other files.

Therefore, turn the variable for the file in the httpd.c file into an array

`**static**``FIL``MyFile**[8]**;`

Also in this file is the entry of the line **Myfile** replace with a string **MyFile [ sn ]**.

B [**next part**](https://narodstream.ru/stm-urok-93-lan-w5500-http-server-sokety-chast-2/) lesson we will fix the code of the function of receiving and processing HTTP packages and check our code in practice.

[Embedded media](https://www.youtube.com/embed/BUZa29YPN7Y)

---

Source: https://maker.wiznet.io/teddy/projects/stm-lesson-93-lan-w5500-http-server-sockets-part-1/
