реклама на сайте
подробности

 
 
> Сервер На Wiznet W5500, передать изображение
mr_smit
сообщение May 12 2015, 04:30
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



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

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

<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 редакторе и сделал массив сырых данных:
CODE
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 заголовку приклеиваем сырые данные картинки.

CODE
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;
}


В итоге запрос на картинку в браузере идет, но сервер её не отдает.
Прикрепленное изображение

При этом браузер получает заголовки ответа. Но самого изображения нет.

От безысходности установил HTTP снифер Wireshark. Удалось выяснить, что при передаче картинки сервер отправляет только её первые 8 байт. И на этом всё.
Прикрепленное изображение


3-й день бьюсь. Не понимаю почему так происходит. Или где то функцию отправки надо изменить или с размером передаваемых данных что то не то. Гуглил и по W5100 и по W5200 и по W5500, но именно как передать изображение не нашел.

Прикрепленный файл  web_discovery_w5500_sd.zip ( 557.27 килобайт ) Кол-во скачиваний: 45


Может есть у кого какие идеи?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
mr_smit
сообщение May 13 2015, 17:56
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



Цитата(AlanDrakes @ May 13 2015, 18:46) *
Кстати, его код пробовали разобрать для понимания? То есть, его последовательность действий:
Чтение файла, обработка, передача... и т.п.?

Так я его исходник и правлю. Функция Send, как я понимаю, сама следит за передающим буфером:
CODE
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;
}


А отправляет он так:
Код
if(fs[sn].fsize != sentsize[sn])
                {

                  f_read(&fs[sn], &buf[header_sz], DATA_BUF_SIZE-header_sz, &blocklen);

                   ret = send(sn,buf,blocklen+header_sz);

                   if(ret < 0)
                   {
                    f_close(&fs[sn]);
                    close(sn);
                    return ret;
                   }

                  sentsize[sn] += ret; // Don't care SOCKERR_BUSY, because it is zero.
                 }

Читает с карты 2048 байт минус размер HTTP заголовка (DATA_BUF_SIZE-header_sz). А отправляет по факту каждый раз 2048 байт (blocklen+header_sz) кроме последней итерации.

Сейчас только заметил blocklen+header_sz. Может надо HTTP заголовок отправлять с каждым куском данных??? Я то сейчас отправляю заголовок, а потом просто куски картинки. А у него в буфере каждый раз оказывается заголовок + новая порция считанных данных &buf[header_sz]. Правильно?

Сообщение отредактировал IgorKossak - May 14 2015, 12:28
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
kolobok0
сообщение May 13 2015, 19:01
Сообщение #3


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(mr_smit @ May 13 2015, 20:56) *
Код
...                 f_read(&fs[sn], &buf[header_sz], DATA_BUF_SIZE-header_sz, &blocklen);

                   ret = send(sn,buf,blocklen+header_sz);
...

Читает с карты 2048 байт минус размер HTTP заголовка...


ышо 5 копеек.
Вы попали в типичную ошибку для протокола TCP. Это протокол ПОТОКОВЫЙ(!) т.е. при вычитывании из буффера может прийти ЛЮБОЕ
кол-во байт в пределах максимально переданного кол-ва. Т.е.

Передатчик передаёт
500+500+24
Приёмник МОЖЕТ принять
24+100+100+300+400+50+50

почувствуйте разницу...
PS
Особенно эти ослинные уши начинают лезть, когда система начинает работать в боевых сетях - с различным временным лагом
прихода пакетов на IP уровне, с доп. разборкой-сборкой на IP уровне, и т.д..

Сообщение отредактировал kolobok0 - May 13 2015, 19:03
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- mr_smit   Сервер На Wiznet W5500, передать изображение   May 12 2015, 04:30
- - AlanDrakes   Вы пытаетесь поместить бинарный файл в строку. Код...   May 12 2015, 05:12
|- - mr_smit   Цитата(AlanDrakes @ May 12 2015, 09:12) Н...   May 12 2015, 05:51
- - mr_smit   Кодstrcat((char*)buf, http_header_end...   May 12 2015, 07:56
|- - kolobok0   Цитата(mr_smit @ May 12 2015, 10:56) .......   May 12 2015, 08:35
|- - AlanDrakes   Цитата(mr_smit @ May 12 2015, 13:56) Кодs...   May 13 2015, 04:06
- - mr_smit   Цитата(kolobok0 @ May 12 2015, 12:35) кон...   May 12 2015, 09:08
- - mr_smit   В общем работают оба способа. Если при запросе кар...   May 12 2015, 16:27
- - mr_smit   Кодint32_t send(uint8_t sn, uint8_t * buf, uin...   May 13 2015, 09:17
- - mr_smit   Сделал так: Кодret = send(sn,buf,size); /...   May 13 2015, 13:23
- - AlanDrakes   Передавать нужно, убедившись, что сокет готов отпр...   May 13 2015, 14:46
- - mr_smit   Цитата(kolobok0 @ May 13 2015, 23:01) Пер...   May 14 2015, 03:26
|- - kolobok0   Цитата(mr_smit @ May 14 2015, 06:26) Выхо...   May 14 2015, 19:04
- - AlanDrakes   Нет, по идее, не нужно к каждой посылке прикреплят...   May 14 2015, 09:59
- - mr_smit   И всё равно я не могу передать изображение Взял p...   May 17 2015, 15:52
- - AlanDrakes   Опять же, попробуйте так: Кодsend_bytes: integ...   May 18 2015, 15:12


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 00:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01395 секунд с 7
ELECTRONIX ©2004-2016