WIZnet Developer Forum

How to send image to client?

Hello, poligon.
I am not sure that you know about sockets with w5500.
w5500 support 8 independent sockets and has commom register,8 socket register, tx/rx buffer for each socket.
But the point is each socket is allocated with 2KB in one 16KB memory buffer. (you can figure it out with w5500 datasheet).
In my view, the reason why browser doesn’t display 5KB pic is it didn’t send well through 1 socket with 2KB and sometimes, it happens.
So, I may tell you need to extend socket buffer size over 5KB.
The initial allocated 2KB size of Socket n TX/RX Buffer can be reallocated by using ‘Socket n TX Buffer Size Register (Sn_TXBUF_SIZE)’ and ‘Socket n RX Buffer Size Register (Sn_RXBUF_SIZE)’. (refer the registers in ‘Chapter 4.2’, w5500 datasheet)
If do not need to use 8 socket all, it is worthy to extend socket buffer size.

The example is a server application that waits on 8 opened listen sockets and when a client connects at one of them it answers: so can have 8 clients connected simultaneously.
You can decide that a socket can respond only to an HTTP GET request ( es: “/index.html” or “/image1.jpg” ) , but you can not divide the answer using multiple socket because only one of these is the connected socket that requires a single object at time.
You can resize only the buffer you use for the images in order to respond with a suitable buffer and decrease those respond html.
Keep in mind that in an embedded HTTP server application can never meet too many clients at the same time… the request/response must become one shot as possible and you must disconnect the socket after answering.

I repeat…
you can not divide the answer using multiple socket because only one of these is the connected socket that requires a single object at time.
The browser not opens second sockets for a single request !!

A possibile solution is this :

  • one ( or more ) socket with small TX buffer size listen on port 80 that respond at html page (containing “” )
  • one socket with large TX buffer size listen on other port ( like 88 ) that respond at “

Browser first load HTML page then with a second socket load myimage.png

to be given: the W5500 can set all the socket for receiving the same port ( as in the example link)
In your case you need to give at one of them a greater buffer and force the client that requires the image to use it.
You can split the image into pieces and respond only ever on the socket that sent the request, but you have to send the block before the transmit buffer is overwritten (because it is a continuous loop)

So…
Read the TX buffer position by reg Sn_TX_WR0
Write into TX buffer until the size of the buffer - 1
Write buffer position in Sn_TX_WR0 ( previous value increased by block size )
Write Sn_CR register with Sn_CR_SEND value
Wait for it to execute the task by reading the register Sn_CR
Reading Sn_IR register for any timeout testing Sn_IR_SENDOK or Sn_IR_TIMEOUT condition ( and if Sn_IR_SENDOK all is done otherwise socket is losed so close it and abandons all )
if all ok, not close the socket but repeat everything to the next block

All this must be carried out in the browser timeout (almost always 30 seconds).
Pay attention to Sn_TX_WR0 : as the connection is almost certainly 0 but then it shifts when write between the different blocks.
Examples of code written in C ++ (for the DHCP and DNS) that are on the site contain all the functions for this purpose.
If you get on with the structured BASIC can have a look here http://www.firewing.info/pmwiki.php?n=FirewingUser.W5500 there is no a specific example of this but I have used the buffer asynchronously starting from the C ++ libraries above.

If it says that it is difficult … but the multi thead on a device is incorrect.
I do not understand what can be attributed to the manufacturer with respect to libraries if they are specific to the MPU you use.
Clearly if you are using an Arduino it becomes easier (https://github.com/Wiznet/WIZ_Ethernet_Library) but for other MPU you are forced to start from something that exists and you have a good knowledge of the MPU.

The YouTube link you are referring to is a client application Pachube for Arduino (http://arduhome.jimdo.com/pachube/) and as far as I know the embedded send basic data format to the server that processes the request after your subscription.
The result you see is not generated by your MPU but by the server that made a rendering of your data.

Hi Poligon,
since this thing intrigued me and like I said I had never tried to send breaking a higher content of the buffer in several parts I wanted to try it and my library PIC18 ( also this roughly translated from C ++) work correctly (tested up to 64K approximately with a 2K buffer and 1K data chunks ).
The sequence I used is as I wrote in this post [url]How to send image to client?] except that I was far from the last character of the buffer because even with this PIC18 I can not create a temporary buffer with more than 1024 bytes.
Try expanding blocks number decreasing the size of the data in the block thus not reaching the buffer overrun.
One important thing : I do not use the Send () but I read the current position of the TX buffer before writing, then write the block into TX Buffer, I tell to W5500 to send the TX Buffer, then I reread the position for each new block and repeat until the end of my buffer and then close the socket.
PS : I confirm up to 256 blocks of 1000 chars plus an html header of 27 bytes.

As I told you my knowledge are the PIC18 / PIC24 and BASIC.
Since it is from source C ++ you are using that I am started for my library we can easily return …
The Send() function performs checks on the transmit buffers that prevent the overrun but inside are some arguments that interest you to make a “multipart” transfer.

Original Send() function :

int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
{
   uint8_t tmp=0;
   uint16_t freesize=0;
   
   CHECK_SOCKNUM();
   CHECK_SOCKMODE(Sn_MR_TCP);
   CHECK_SOCKDATA();
   tmp = getSn_SR(sn);
   if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
   if( sock_is_sending & (1<<sn) )
   {
      tmp = getSn_IR(sn);
      if(tmp & Sn_IR_SENDOK)
      {
         setSn_IR(sn, Sn_IR_SENDOK);
         #if _WZICHIP_ == 5200
            if(getSn_TX_RD(sn) != sock_next_rd[sn])
            {
               setSn_CR(sn,Sn_CR_SEND);
               while(getSn_CR(sn));
               return SOCKERR_BUSY;
            }
         #endif
         sock_is_sending &= ~(1<<sn);         
      }
      else if(tmp & Sn_IR_TIMEOUT)
      {
         close(sn);
         return SOCKERR_TIMEOUT;
      }
      else return SOCK_BUSY;
   }
   freesize = getSn_TxMAX(sn);
   if (len > freesize) len = freesize; // check size not to exceed MAX size.
   while(1)
   {
      freesize = getSn_TX_FSR(sn);
      tmp = getSn_SR(sn);
      if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
      {
         close(sn);
         return SOCKERR_SOCKSTATUS;
      }
      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
      if(len <= freesize) break;
   }
   wiz_send_data(sn, buf, len);
   #if _WIZCHIP_ == 5200
      sock_next_rd[sn] = getSn_TX_RD(sn) + len;
   #endif
   setSn_CR(sn,Sn_CR_SEND);
   /* wait to process the command... */
   while(getSn_CR(sn));
   sock_is_sending |= (1 << sn);
   return len;
}

… so from Send() function you can use :

getSn_TX_RD(sn)  is the function that will return the position of the transmission buffer
wiz_send_data()   store a given buffer in W5500 TX buffer ( must adapt params for your main) )
setSn_CR(sn,Sn_CR_SEND)  make the transfer
while(getSn_CR(sn))  is the waiting loop for completion

The rest are just controls on buffer overrun, but that is under control if you manage as will I had said in previous posts.
If you can read BASIC sources ( here [url]How to send image to client?] :unamused:) there are no problems talking about it or extract what you need.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.