---
title: "UDP server stop working after a while"
url: "https://maker.wiznet.io/forum/11795"
markdown_url: "https://maker.wiznet.io/forum/11795/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "cio74"
created: "2016-04-14T17:01:27+09:00"
last_activity: "2024-03-27T06:58:44+09:00"
language: "en"
views: 3465
replies: 24
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# UDP server stop working after a while

## Question

Asked by cio74 on 2016-04-14 in Ethernet Chips.

Hello,

I have setup 4 sockets, 2 TCP servers, 1 TCP client and 1 UDP server. Using W5500 and ARM M4.

On a PC machine I have an UDP client and another UDP server. The client send a packet to 255.255.255.255, broadcast on a specified port. The W500 UDP server is supposed to get that packet and close the connection.

Everything works just fine but at some point the UDP server stops working. The client keeps broadcasting but on the W5500 side no longer acknowledges the packet.

This si what it;'s on the W5500 side while loop

```
    ...
    uint8_t udp_socket_message = getSn_SR(udpServerSocket);
    switch(udp_socket_message)
    {
      case SOCK_UDP:;        
        uint32_t udpRecvSize = getSn_RX_RSR(udpServerSocket);
        if (udpRecvSize > 0) 
        ....
     }
     disconnect(udpServerSocket);
     ...
```

The problem is that udpRecvSize is being reported as 0 when the problem occurs.

Board reset will fix the issue and repeated broadcast messages are processed correct but later it stops working again.

Should I do a specific check prior to calling genSn_SR?

Thanks.

## Replies

### Reply 1 by Eugeny, 2016-04-14

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> The problem is that udpRecvSize is being reported as 0 when the problem occurs.

Thus the problem is that at some point in time W5500 stops receiving broadcast packets, right?

Do W5500-based TCP servers continue working when it happens?
If yes, please make dump of all the registers from UDP socket to see if they are not corrupt and still reflect proper operating mode. Also please dump Sn_RXBUF_SIZE of all sockets to ensure they all are still configured properly and space does not exceed size of RX memory.

### Reply 2 by cio74, 2016-04-14

Yes, all the other TCP sockets are working fine.

I get your point but the question is when to check the registers? Shall I assume that if GetSn_SR returns SOCK_UDP there is always something in the receive buffer and the size returned by getSn_RX_RSR should be always greater than 0? And if it’s 0 then something is wrong and I shall check the registry?

Thanks.

### Reply 3 by Eugeny, 2016-04-14

Works = W5500 receives packets. Stops working = remote device sends packets, but W5500 does not receive them (RSR is 0).
Check when it stops working = something has changed, we need to ensure that everything on W5500 side is intact.
If W5500’s registers are ok, then probably something wrong is with packets - check them using Wireshark to see that they contain what you expect W5500 to get (in terms of UDP header and packet contents).
You send broadcast packets and you will be able to see them using any device on the same physical network.

### Reply 4 by cio74, 2016-04-14

I am using Wireshark for debugging, that’s how I see what’s being sent and received, I’ll add the registers dump code and hopefully capture an exception to check what’s in there.

I’ll keep you posted.

### Reply 5 by cio74, 2016-04-14

Not sure about that, I got 0 received length at startup, before sending anything. reg dumps

getSn_MR 02
getSn_CR 00
getSn_IMR 1F
getSn_IR 00
getSn_SR 22
getSn_MSSR C0
getSn_TX_RD 00
getSn_RX_RD 00
getSn_TX_FSR 00
getSn_KPALVTR 00

UDP getSn_RXBUF_SIZE 01
UDP getSn_TXBUF_SIZE 01

FW getSn_RXBUF_SIZE 02
FW getSn_TXBUF_SIZE 02

WEB SERVER getSn_RXBUF_SIZE 04
WEB SERVER regWEB_Sn_TXBUF_SIZE 04

TCP Client getSn_RXBUF_SIZE 00
TCP Client getSn_TXBUF_SIZE 00

TCP Server getSn_RXBUF_SIZE 08
TCP Server getSn_TXBUF_SIZE 08

TCP client was not initialized at that point.

All buffers are fine, as per socket buffer definition:

uint8_t txSize[*WIZCHIP_MAX_SOC_NUM*] = {0,0,8,4,2,1,1,0};
uint8_t rxSize[*WIZCHIP_MAX_SOC_NUM*] = {0,0,8,4,2,1,1,0};

However, it works and does reply to packets, when no packets are sent by PC client getSn_RX_RSR returns 0.

### Reply 6 by Eugeny, 2016-04-14

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> Not sure about that, I got 0 received length at startup, before sending anything. reg dumps

I am sorry I do not understand you. RSR is received data size. If nothing is received, it is 0. It is normal state, nothing special about it.
If chip did not receive anything its RSR is 0, and this is how you identify if it received anything.
In the dump below you write

> getSn_TX_FSR 00

This is strange because if TX buffer is empty it is set to maximum 0x800, and it is two byte (word) value, you display it as one byte. I would expect you identifying it as 0000 or 0800 (this is how it normally looks like if there’s nothing in TX buffer to send).

### Reply 7 by cio74, 2016-04-14

Obviously we were talking about different things, I was asking if the recv value of 0 means there is a fault and I have thought it is.

Shall RTFM but I won’t exactly call W5500 datasheet a good source of info. Same about W5100, just basics.

Is anyone using this chip in a commercial product or is all hobby development?

### Reply 8 by Eugeny, 2016-04-14

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> Shall RTFM but I won’t exactly call W5500 datasheet a good source of info. Same about W5100, just basics.

Yes please study W5100 - it seems to have more useful information on how to use the chip family.

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> Is anyone using this chip in a commercial product or is all hobby development?

Let’s think about it differently - can the chip family satisfy commercial product’s requirements? I do not know about WIZnet strategy regarding their product development and product roadmap, but it is clear that products are having hardware limitations (like buffer memory and number of sockets) which can not be changed by additional hardware design (e.g. by adding SRAM chip to get more socket memory), but at the same time WIZnet chips provide extremely easy product development if you know how to apply them properly.

### Reply 9 by cio74, 2016-04-14

Lets read between the lines and agree it’s not suitable for commercial products, a good commercial product has good support, this one does not. I am quite certain you can’t get support even if you want to pay for it. Should be good enough for a hobby project tho.

About “if you know how to” well, people don’t get the knowledge from the sky. They read proper documents with proper examples and case studies. When they don’t have these they spend time debugging and understanding how it works. May as well ask in a forum where no one from the manufacturer bother to reply. Rant over, going back to the datasheet ![:slight_smile:](https://emoji.discourse-cdn.com/twitter/slight_smile.png?v=12)

### Reply 10 by Eugeny, 2016-04-14

[quote=“cio74”]I am quite certain you can’t get support even if you want to pay for it. Should be good enough for a hobby project tho.
…
When they don’t have these they spend time debugging and understanding how it works.
[/quote]
That’s why I am here… I got to know how it works - you can look at the history of my posts - we have eaten a ton of sh*t together with WIZnet people until we found out what was wrong with my design.

### Reply 11 by cio74, 2016-04-14

I have managed to replicate the issue, this are the registry at the time the fault occurs

[ul]
getSn_MR 02
getSn_CR 00
getSn_IMR 1F
getSn_IR 04
getSn_SR 22
getSn_MSSR 05C0
getSn_TX_RD 0980
getSn_TX_WR 0980
getSn_RX_RD 00DC
getSn_RX_WR 00DC
getSn_TX_FSR 0400
getSn_KPALVTR 00
UDP getSn_RXBUF_SIZE 01
UDP getSn_TXBUF_SIZE 01
FW getSn_RXBUF_SIZE 02
FW getSn_TXBUF_SIZE 02
WEB SERVER getSn_RXBUF_SIZE 04
WEB SERVER regWEB_Sn_TXBUF_SIZE 04
TCP Client getSn_RXBUF_SIZE 00
TCP Client getSn_TXBUF_SIZE 00
TCP Server getSn_RXBUF_SIZE 08
TCP Server getSn_TXBUF_SIZE 08
[/ul]

### Reply 12 by Eugeny, 2016-04-15

I do not see source port # (Sn_PORT) and RX received size (Sn_RX_RSR) in the dump. If port # is wrong, I think chip will not receive anything even as broadcast. Does your UDP access algorithm obey pages 50-55 of the W5100 datasheet? Don’t you forget to update RX_RD pointer and issue RECV command after you process received packet(s)?
Edit: and while you have only 1K buffer for UDP socket (0-3ff), you update all pointers using 16-bit math (e.g. RX_RD=03e5, data received is 0040 → new RX_RD is 0425 and not 0025) while data buffer position within its window will be 025.

### Reply 13 by cio74, 2016-04-15

I do not manually update any register, not sure why do I have to do that anyway, do you happen to know the answer?

Sn_RX_RSR is 0, see initial post, the dump is when recv value is 0

### Reply 14 by Eugeny, 2016-04-15

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> I do not manually update any register, not sure why do I have to do that anyway, do you happen to know the answer?

Simple question: how do you think W5500 will know that you grabbed data it received before it will reuse same its memory cells to put new packet into? Download W5100 datasheet, and thoroughly read pages 50-55 about UDP. It explains what should happen to W5100 (5500) registers for it to properly continue receiving and sending data. Please note that I said “what should happen” and not “what you should do” ![:blush:](https://emoji.discourse-cdn.com/twitter/blush.png?v=12) because I do not know how you program the chip and which routines you use to program it (the code is “…” in your first post in this thread).

### Reply 15 by cio74, 2016-04-15

The chip logic knows I have issued a read command and can update it’s offset, it returns the length of the read command, it knows where to move the pointer.

Yes, I have seen the datasheet, I am asking what’s the logic behind it.

Edit: have read the library code and it does update the Sn_RX_RD

```
int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
{
   uint8_t  tmp = 0;
   uint16_t recvsize = 0;
   CHECK_SOCKNUM();
   CHECK_SOCKMODE(Sn_MR_TCP);
   CHECK_SOCKDATA();
   
   recvsize = getSn_RxMAX(sn);
   if(recvsize < len) len = recvsize;
   while(1)
   {
      recvsize = getSn_RX_RSR(sn);
      tmp = getSn_SR(sn);
      if (tmp != SOCK_ESTABLISHED)
      {
         if(tmp == SOCK_CLOSE_WAIT)
         {
            if(recvsize != 0) break;
            else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
            {
               close(sn);
               return SOCKERR_SOCKSTATUS;
            }
         }
         else
         {
            close(sn);
            return SOCKERR_SOCKSTATUS;
         }
      }
      if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
      if(recvsize != 0) break;
   };
   if(recvsize < len) len = recvsize;
   wiz_recv_data(sn, buf, len);
   setSn_CR(sn,Sn_CR_RECV);
   while(getSn_CR(sn));
   return len;
}
```

```
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
   uint16_t ptr = 0;
   uint32_t addrsel = 0;
   
   if(len == 0) return;
   ptr = getSn_RX_RD(sn);
   addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
   WIZCHIP_READ_BUF(addrsel, wizdata, len);
   ptr += len;
   
   setSn_RX_RD(sn,ptr);
}
```

So it’s all there.

### Reply 16 by cio74, 2016-04-15

Something else is the issue, not ordinary read/write, this works and it just stops working under a specific scenario.

I have managed to easily reproduce the issue, if I access the web server socket then the UDP server issue is generated, always recv returns 0 and the previous registers dump applies.

### Reply 17 by Eugeny, 2016-04-15

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> I have managed to easily reproduce the issue, if I access the web server socket then the UDP server issue is generated

Which source ports you use for web server and UDP server?

### Reply 18 by cio74, 2016-04-15

No port for server, just socket library used.

All socket servers are following the below basic implementation.

Create socket, init socket, then a loop made of:

```
  while (1) {
    switch(getSn_SR(tcpSocket)){
      case SOCK_LISTEN: break;
      case SOCK_ESTABLISHED: do work here; break;
      case SOCK_CLOSE_WAIT: disconnect(tcpSocket); break;
      case SOCK_INIT: listen(tcpSocket); break;
      case SOCK_CLOSED: if( !socket(tcpSocket, Sn_MR_TCP, netIPPort, 0x00) ) ...; break; //re-use socket
      default: break;
   }
```

and on the UDP server

```
   while(1){
     uint8_t udp_socket_message = getSn_SR(udpServerSocket);
     switch(udp_socket_message){
       case SOCK_UDP: do work here; disconnect(udpServerSocket); break;
       case SOCK_LISTEN: break;
       case SOCK_ESTABLISHED: break;
       case SOCK_CLOSE_WAIT: disconnect(udp_socket_message); break;
       case SOCK_INIT: listen(udp_socket_message); break;
       case SOCK_CLOSED: if(!socket(udp_socket_message, Sn_MR_UDP, UDP_SERVER_PORT, 0x00)) ...; break; //re-use socket
     }
```

while copy/paste this code it struck me the name of the socket variable, should be ‘udpServerSocket’ and not ‘udp_socket_message’

Changed it and of course now all works just fine. Code completion on IDE’s is not always great so does poor variable definition with ambiguous/similar named.

Anyway, looking above, as a generic server implementation, are the cases doing what they should, do I miss a specific case or any recommendation.

Thanks.

### Reply 19 by Eugeny, 2016-04-15

Do I understand properly that now your application works properly and the cause was that you forgot to initialize source port numbers at W5500 side?
Because I do not see your answer regarding source port numbers on the sockets. It is one of the weak points in standard libraries and some people had problems due to it.
Or it is only and just using wrong variable because names looks similar…

### Reply 20 by cio74, 2016-04-15

Eugeny:

> …Or it is only and just using wrong variable because names looks similar…

that

Since you have worked quite a lot with this chip, would you recommend other actions to be performed or added in the case switch operations?

### Reply 21 by Eugeny, 2016-04-15

![](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/48.png) cio74:

> in the case switch operations?

What is switch operations in your context?

### Reply 22 by cio74, 2016-04-15

Sorry, I have mean the C case handling

```
 while(1){
     uint8_t udp_socket_message = getSn_SR(udpServerSocket);
     switch(udp_socket_message){
       case SOCK_UDP: do work here; disconnect(udpServerSocket); break;
       case SOCK_LISTEN: break;
       case SOCK_ESTABLISHED: break;
       case SOCK_CLOSE_WAIT: disconnect(udp_socket_message); break;
       case SOCK_INIT: listen(udp_socket_message); break;
       case SOCK_CLOSED: if(!socket(udp_socket_message, Sn_MR_UDP, UDP_SERVER_PORT, 0x00)) ...; break; //re-use socket
     }
```

How would you normally thread each SnSR status after reading it. Do you check all socket status or just a few? Anything specific you recommend.

Thanks.

### Reply 23 by Eugeny, 2016-04-15

What I can tell you that you have two vehicles how to check status of the socket - through interrupts (using IMR/IR register and/or hardware interrupt line itself), and through status register. They can and should be combined. However if you use only SR then it gives full understanding of the state, but using interrupt you only get notification on state change and anyway need to use SR. Probably it is not applicable to you project, but just keep it in mind.
Regarding your question on the case statement - it is just initial example how it could look like, the implementation fully depends on your needs - how you query sockets and their statuses, when you send data to remote peer (in terms of high level communication implementation), and how you manage concurrent data transfers. And from low level implementation access and process flow of the socket should obey those W5100 manual pages about TCP server/client and UDP.
About process flow: you can see it in manual, also see diagram on page 28 (it is a little messy, but as you study the process you will be able to understand it in full). There’re some status codes which are not listed BTW, but the idea for TCP that socket sequentially passes all the stages from 0x13 to 0x1E (or so). If socket has stuck in some state, you probably did something wrong before - in this connection or in managing/closing previous connection. Depends on scenario.

### Reply 24 by Zmi nazim, 2018-10-25

When I try and connect using different computers at first it works but after some time it just stops; the connection is “terminated”. Also, ignore the `game.player` stuff, it is just a player of mine.

This is my code:

Client:

```
public class GameClient extends Thread {
  private InetAddress ipAddress;
  private DatagramSocket socket;
  private Main game;

  public GameClient(Main main, String ipAddress) {
    this.game = main;
    try {
      this.socket = new DatagramSocket();
      this.ipAddress = InetAddress.getByName(ipAddress);
    } catch (SocketException e) {
      e.printStackTrace();
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }
  }
  public void run() {
    while (true) {
      byte[] data = new byte[1024];
      DatagramPacket packet = new DatagramPacket(data, data.length);
      try {
        socket.receive(packet);
      } catch (IOException e) {
        e.printStackTrace();
      }
      String message = new String(packet.getData());
      message = message.trim();
      if (message.startsWith("00")) {
        System.out.println("Player connected. Got server response...");
        String msg = "01" + game.player.getPos();
        sendData(msg.getBytes());
      }
      if (message.startsWith("01")) {
        message = message.substring(2);
        List<String> coords = Arrays.asList(message.split(","));
        game.updateMP(coords);
see: https://luckypatcher.pro/
https://kodi.software/
https://plex.software/
```

---

Source: https://maker.wiznet.io/forum/11795
