Сервер на WIZnet W5500, отправить изображение

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сервер на WIZnet W5500, отправить изображение

Сообщение mr_smit »

Прикупил у китайцев плату с чипом W5500. Это обновленная версия Ethernet чипа W5100. Подключил к STM32 Discovery. За основу взял эту статью: http://we.easyelectronics.ru/GYUR22/w55 ... erver.html. Убрал функции работы с SD картой и с горем пополам скомпилировал всё это в CooCox. Сервер заработал. Т.е. отдает в браузер статичный текст.

Хочу добавить на html страницу картинку. Для теста сделал PNG размером 5х5 пикселей. Добавил её в html код:

Код: Выделить всё

<html>
<head>
<title>Умный дом</title>
<meta http-equiv='content-type' content='text/html; charset=windows-1251'>
</head>
<body>
<br><br><br><center><b>Тестовая страница W5500</b></center><br>
<center><img src='test.png'></center>
</body>
</html>
Открыл картинку в hex редакторе и сделал массив сырых данных:

Код: Выделить всё

const char Img [205] =
{
0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x05,
0x00,0x00,0x00,0x05,0x08,0x02,0x00,0x00,0x00,0x02,0x0D,0xB1,0xB2,0x00,0x00,0x00,0x01,0x73,0x52,0x47,
0x42,0x00,0xAE,0xCE,0x1C,0xE9,0x00,0x00,0x00,0x06,0x62,0x4B,0x47,0x44,0x00,0xFF,0x00,0xFF,0x00,0xFF,
0xA0,0xBD,0xA7,0x93,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0B,0x13,0x00,0x00,0x0B,0x13,
0x01,0x00,0x9A,0x9C,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4D,0x45,0x07,0xDF,0x05,0x0A,0x0E,0x01,0x20,
0xA0,0x0A,0x57,0xCD,0x00,0x00,0x00,0x19,0x74,0x45,0x58,0x74,0x43,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x00,
0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4D,0x50,0x57,0x81,0x0E,
0x17,0x00,0x00,0x00,0x28,0x49,0x44,0x41,0x54,0x08,0xD7,0x4D,0x8B,0x41,0x0E,0x00,0x30,0x08,0xC2,0xA8,
0xFF,0xFF,0x73,0x3D,0x18,0xDD,0xB8,0x34,0x94,0x40,0x12,0x35,0x9B,0x52,0x81,0xD7,0x67,0x3F,0x55,0x83,
0x53,0xFC,0x67,0xA0,0x01,0x8E,0xCE,0x0F,0x06,0x6E,0x28,0x44,0x78,0x00,0x00,0x00,0x00,0x49,0x45,0x4E,
0x44,0xAE,0x42,0x60,0x82
};
А в функции tcp_http_mt добавил реакцию на запрос картинки. Т.е. при ответе к HTTP заголовку приклеиваем сырые данные картинки.
Спойлер

Код: Выделить всё

int32_t tcp_http_mt(uint8_t sn, uint8_t* buf, uint16_t port)
{
   int32_t ret;
   uint32_t size = 0;
   char *url,*p;

   switch(getSn_SR(sn))
   {
      case SOCK_ESTABLISHED :

         if(getSn_IR(sn) & Sn_IR_CON)
         {
            setSn_IR(sn,Sn_IR_CON);
         }

         if((size = getSn_RX_RSR(sn)) > 0)
         {
            if(size > DATA_BUF_SIZE)
            {
            	size = DATA_BUF_SIZE;
            }

            ret = recv(sn,buf,size);

            HTTP_reset(sn);

            if(ret <= 0)
            {
            	return ret;
            }

            url =(char*) buf + 4;

            if((http_state[sn]==HTTP_IDLE)&&(memcmp(buf, "GET ", 4)==0)&&((p = strchr(url, ' '))))  // extract URL from request header
            {
              *(p++) = 0;   //making zeroed url string

              sentsize[sn]=0;

              if(strcmp(url,"/")==0)
              {
                strcpy((char*)buf,http_200);
                strcat((char*)buf, http_server);
                strcat((char*)buf,"Content-Type: text/html; charset=windows-1251\r\n");
                strcat((char*)buf,"Cache-Control: no-cache\r\n");
                strcat((char*)buf,http_connection_close);
                strcat((char*)buf, http_header_end);
                strcat((char*)buf,site);
                size=strlen((char*)buf);
                http_state[sn]=HTTP_SENDING;
              }

              if(strcmp(url,"/test.png")==0)
                            {
                              strcpy((char*)buf,http_200);
                              strcat((char*)buf, http_server);
                              strcat((char*)buf,"Content-Type: image/png\r\n");
                              //
                              strcat((char*)buf,"Content-Lenght: 205\r\n");
                              strcat((char*)buf,"Connection: keep-alive\r\n");
                              strcat((char*)buf,"Keep-Alive: timeout=20\r\n");
                              strcat((char*)buf,"Accept-Ranges: bytes\r\n");
                              strcat((char*)buf,"Cache-Control: no-cache\r\n");
                              strcat((char*)buf, http_header_end);
                              strcat((char*)buf,Img);
                              size=strlen((char*)buf);
                              http_state[sn]=HTTP_SENDING;
                            }
            }

/*
           Отправляем данные пока размер отправленных данных sentsize[sn] не сравняется с размером данных size
           которые мы подготовили для отправки

... вроде бы...
*/
           if(http_state[sn]==HTTP_SENDING)
            {
        	   while (sentsize[sn] < size)
        	   {
        		  //DATA_BUF_SIZE

        		ret = send(sn,buf,size);
        	    if(ret < 0)
        	    {
        	     close(sn);
        	     return ret;
        	    }
        	    sentsize[sn] += ret; // Don't care SOCKERR_BUSY, because it is zero.
        	   }
        	  HTTP_reset(sn);
        	  disconnect(sn);
            }
          }

         break;

      case SOCK_CLOSE_WAIT :

    	  HTTP_reset(sn);

         if((ret=disconnect(sn)) != SOCK_OK)
         return ret;

         break;
      case SOCK_INIT :

    	  HTTP_reset(sn);

         if( (ret = listen(sn)) != SOCK_OK) return ret;
         break;
      case SOCK_CLOSED:

    	  HTTP_reset(sn);

         if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
         return ret;

         break;

      default:
    	  HTTP_reset(sn);
         break;
   }
   return 1;
}
В итоге запрос на картинку в браузере идет, но сервер её не отдает.
Html.png
(101.78 КБ) 730 скачиваний
При этом браузер получает заголовки ответа. Но самого изображения нет.

От безысходности установил HTTP снифер Wireshark. Удалось выяснить, что при передаче картинки сервер отправляет только её первые 8 байт. И на этом всё.
PNG.png
(150.99 КБ) 656 скачиваний
3-й день бьюсь. Не понимаю почему так происходит. Или где то функцию отправки надо изменить или с размером передаваемых данных что то не то. Гуглил и по W5100 и по W5200 и по W5500, но именно как передать изображение не нашел.
web_discovery+w5500_sd.zip
(557.27 КБ) 248 скачиваний
Кто чем может.
Нельзя всё знать, достаточно понимать.
Реклама
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение mr_smit »

И всё равно я не могу передать изображение :( Взял png изображение размером 2179 байт. Открыл через HEX редактор. Создал массив байт:

Код: Выделить всё

const char Img [2179] =
{
0x89,0x50,0x4E,0x47,0x0D...
...
};
И пробую передать по запросу в браузер. В состоянии http_state[sn]==HTTP_IDLE формирую заголовок:

Код: Выделить всё

if(strcmp(url,"/test.png")==0)
			  {
				strcpy((char*)buf,http_200);
				strcat((char*)buf, http_server);
				strcat((char*)buf,"Connection: close\r\n");
				strcat((char*)buf,"Content-Length: ");
				itoa(sizeof(Img),str);
				strcat((char*)buf,str);
				strcat((char*)buf,"\r\n");
				strcat((char*)buf,"Content-Type: image/png\r\n");
				strcat((char*)buf, http_header_end);
				header_sz=strlen((char*)buf);
				http_state[sn]=HTTP_SENDING;
			  }
В состоянии http_state[sn]==HTTP_SENDING отправляю изображение по частям:

Код: Выделить всё

if(http_state[sn]==HTTP_SENDING)
		 {
			 ret = send(sn,buf,header_sz);   // заголовок
			 ret = send(sn,&Img[0],2048);	// первые 2048 байт изображения
			 ret = send(sn,&Img[2048],130);  // остаток
			 HTTP_reset(sn);
			 disconnect(sn);
		 }
В итоге при обращении по адресу 192.168.1.25/test.png браузер показывает изображение, но только эти первые 2048 байт. Последние байты не отображаются. Т.е. не передаются.
t.png
(124.35 КБ) 435 скачиваний
Я не понимаю почему так. Хоть убейте. Почему при вызове функции send второй раз она ничего не передает??
Нельзя всё знать, достаточно понимать.
Реклама
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение BorisSPB »

Наверно надо убрать HTTP_reset(sn).
msxfan
Встал на лапы
Сообщения: 147
Зарегистрирован: Пн июн 14, 2010 22:32:36
Откуда: Москва

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение msxfan »

mr_smit писал(а):Я не понимаю почему так. Хоть убейте. Почему при вызове функции send второй раз она ничего не передает??
Добрый день. Предлагаю уменьшить размер первой отправки с 2048 до скажем 1024 или даже 512 байт. Попробуйте вместо одного 2048 четыре по 512.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Ser60
Друг Кота
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение Ser60 »

Согласно Wireshark, при запросе соединения с Вашим сервером (пакет SYN) Gateway сообщает ему максимальную длину принимаемого собщения 1460 байт (это на данные + 40 байт заголовков TCP и IP), а Вы в него все 2048 данных пихаете.
Реклама
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение BorisSPB »

1460 - это размер сегмента, размер окна - 2048 байт.

Код: Выделить всё

ret = send(sn,&Img[0],2048);   // первые 2048 байт изображения
заполняет буфер, а следующее обращение

Код: Выделить всё

ret = send(sn,&Img[2048],130);  // остаток
скорее всего возвращает ret=0, т.к. буфер заполнен, а подтверждение еще не пришло.
Надо анализировать возвращаемое значение.
Реклама
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение mr_smit »

BorisSPB писал(а):

Код: Выделить всё

ret = send(sn,&Img[0],2048);   // первые 2048 байт изображения
заполняет буфер, а следующее обращение

Код: Выделить всё

ret = send(sn,&Img[2048],130);  // остаток
скорее всего возвращает ret=0, т.к. буфер заполнен, а подтверждение еще не пришло.
Надо анализировать возвращаемое значение.
Так функция send возвращает количество реально переданных байт. Пока она не отработает мы на вторую строчку не попадем. Браузер показывает что ровно 2 кБ принял.
Нельзя всё знать, достаточно понимать.
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение BorisSPB »

А функция send точно блокирующая?
А то похоже что соединение на уровне приложения закрывается с заполненным под завязку буфером, буфер в фоновом режиме передается и соединение закрывается на уровне TCP.
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение mr_smit »

Это библиотечная функция. Вот что производитель пишет про неё:
/**
* @ingroup WIZnet_socket_APIs
* @brief Send data to the connected peer in TCP socket.
* @details It is used to send outgoing data to the connected socket.
* @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
* In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
* In non-block io mode, It return @ref SOCK_BUSY immediatly when socket buffer is not enough. \n
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer containing data to be sent.
* @param len The byte length of data in buf.
* @return @b Success : The sent data size \n
* @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCK_BUSY - Socket is busy.
*/
P.S. Чушь какая то:
1_.png
(127.51 КБ) 688 скачиваний
2_.png
(134.42 КБ) 680 скачиваний
Правда я переменную ret сделал глобальной, иначе она в отладчике не отображалась.
Нельзя всё знать, достаточно понимать.
r0cket111
Родился
Сообщения: 9
Зарегистрирован: Пт дек 13, 2013 18:37:51

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение r0cket111 »

Ну и как результат ? что нибудь получилось ?
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Сервер на WIZnet W5500, отправить изображение

Сообщение mr_smit »

Нельзя всё знать, достаточно понимать.
Ответить

Вернуться в «ARM»