Здравствуйте дорогие товарищи программисты.
Проблема: Не принимаются данные в полном объёме с сервера при восылке ему сообщения такого родаchar buf1[] = "GET http://server/ HTTP/1.1\nHost: server\nUser-Agent: Mozilla/5.0\nAccept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\nAccept-Language: en-us,en;q=0.7,ru;q=0.3\nAccept-Encoding: gzip,deflate\nAccept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7\n\n";
Сервер отвечает, но поток данных прерывается по непонятной мне причине, выглядит это примерно такGET http://chittel.ru/ HTTP/1.1
Host: chat.chittel.ru
User-Agent: Mozilla/5.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.7,ru;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7-----------------------
HTTP/1.1 200 OK
Date: Thu, 25 Jan 2007 10:02:45 GMT
Server: Apache/2.0.52 (Lineox)
X-Powered-By: PHP/4.3.9
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=cp125120dd
<HTML>
<HEAD>
<TITLE> </TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<STYLE type="text/css">
<!--
img {
border: none;
}
.tah10 {
font-family: Tahoma;
font-size: 10px;
text-decoration: none;
color: #000000;
}
.tah11 {
font-family: Tahoma;
font-size: 11px;
texВопрос: почему?
Вот кратко кусок кода который соеденяется с сервером, посылает и принимает данные
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("fuck socket re\n");
return(-1);
}if (connect(s, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
{
printf("fuck connect re\n");
close(s);
return(-1);
}
if (send(s, buf1/*core_temp->buf_r_c*/, sizeof(buf1)/*SIZE_BUFF_C*/, 0) < 0 )
{
printf("fuck send re\n");
close(s);
return(-1);
}
printf("debug: send:\n%s", buf1/*core_temp->buf_r_c*/);
while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
{
printf("fuck recv re\n");
close(s);
return(-1);
}Сразу хочется отметить что указатели, указывают на область памяти выделенной с помощью malloc, размер буфера порядка 50000 байт, эксперементировал с разными объёмами.
Заранее благодарен.
>while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
> {
> printf("fuck recv re\n");
> close(s);
> return(-1);
> }А что, по-твоему, должно происходить в этом цикле?
>>while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
>> {
>> printf("fuck recv re\n");
>> close(s);
>> return(-1);
>> }
>
>А что, по-твоему, должно происходить в этом цикле?Соглашусь несколько грубо, применил в самом начале разработки особо не задумываясь.
>HTTP/1.1 200 OK
>Date: Thu, 25 Jan 2007 10:02:45 GMT
>Server: Apache/2.0.52 (Lineox)
>X-Powered-By: PHP/4.3.9
>Connection: close
>Transfer-Encoding: chunked
>Content-Type: text/html; charset=cp1251
>
>20dd
><HTML>
><HEAD>Супер ! По твоему поле "Transfer-Encoding: chunked" просто так выставлено ? Да и какие-то непонятные "20dd" в начале страницы должны были подтолкнуть тебя к правильному решению.
Вообщем это chunked-request. Данные высылаются порциями. В начале каждой порции используется строка, завершенная "\r\n", в которой указано, какое количество байт следует прочитать до следующей порции данных (естественно - в шестнадцатиричной форме). Данные в порции не должны анализироваться при приеме. Т.е. предполагается что данные передаются в бинарном виде, даже если указан "Context-Type: text/html".
>Супер ! По твоему поле "Transfer-Encoding: chunked" просто так выставлено ? Да
>и какие-то непонятные "20dd" в начале страницы должны были подтолкнуть тебя
>к правильному решению.
>
>Вообщем это chunked-request. Данные высылаются порциями. В начале каждой порции используется строка,
>завершенная "\r\n", в которой указано, какое количество байт следует прочитать до
>следующей порции данных (естественно - в шестнадцатиричной форме). Данные в порции
>не должны анализироваться при приеме. Т.е. предполагается что данные передаются в
>бинарном виде, даже если указан "Context-Type: text/html".Но я пробовал операцию приема ставить в цикл, предполагая что могут быть порции, читал одни и теже данные, какое RFC описывает порядок приема(2068???) или другое?
>if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
> {
> printf("fuck socket re\n");
> return(-1);
> }
>
> if (connect(s, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
> {
> printf("fuck connect re\n");
> close(s);
> return(-1);
> }
>
> if (send(s, buf1/*core_temp->buf_r_c*/, sizeof(buf1)/*SIZE_BUFF_C*/, 0) < 0 )
> {
> printf("fuck send re\n");
> close(s);
> return(-1);
> }
>
> printf("debug: send:\n%s", buf1/*core_temp->buf_r_c*/);
>
> while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
> {
> printf("fuck recv re\n");
> close(s);
> return(-1);
> }
>
>Сразу хочется отметить что указатели, указывают на область памяти выделенной с помощью
>malloc, размер буфера порядка 50000 байт, эксперементировал с разными объёмами.
>
>Заранее благодарен.
Дочитав до конца, понял что проблем тут проблем сразу несколько. recv - не может принять порцию больше, чем системный буффер для данного сокета (см. getsockopt(2)/setsockopt(2) опции SO_SNDBUF и SO_RCVBUF). А эти значения для TCP не могут превышать 64K. Изначально пользователю самому предлагается склеить их. Можно также в данном случае рекомендовать вызов write в блокирующем (ждущем) режиме, но и для него нужно предусмотреть прерывание выполнение (например пришедший сигнал для другого потока может прервать его выполенение). Если все же хочется использовать recv - то посмотри на флаг
> return(-1);
> }
>
> printf("debug: send:\n%s", buf1/*core_temp->buf_r_c*/);
>
> while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
> {
> printf("fuck recv re\n");
> close(s);
> return(-1);
> }
>
>Сразу хочется отметить что указатели, указывают на область памяти выделенной с помощью
>malloc, размер буфера порядка 50000 байт, эксперементировал с разными объёмами.
>
>Заранее благодарен.
Дочитав до конца, понял что проблем тут проблем сразу несколько. recv - не может принять порцию больше, чем системный буффер для данного сокета (см. getsockopt(2)/setsockopt(2) опции SO_SNDBUF и SO_RCVBUF). А эти значения для TCP не могут превышать 64K. Изначально пользователю самому предлагается склеить их. Можно также в данном случае рекомендовать вызов write в блокирующем (ждущем) режиме, но и для него нужно предусмотреть прерывание выполнение (например пришедший сигнал для другого потока может прервать его выполенение). Если все же хочется использовать recv - то посмотри на флаг
> return(-1);
> }
>
> printf("debug: send:\n%s", buf1/*core_temp->buf_r_c*/);
>
> while ((n = recv(s, core_temp->buf_r_s, len, 0)) == 0)
> {
> printf("fuck recv re\n");
> close(s);
> return(-1);
> }
>
>Сразу хочется отметить что указатели, указывают на область памяти выделенной с помощью
>malloc, размер буфера порядка 50000 байт, эксперементировал с разными объёмами.
>
>Заранее благодарен.
Дочитав до конца, понял что проблем тут проблем сразу несколько. recv - не может принять порцию больше, чем системный буффер для данного сокета (см. getsockopt(2)/setsockopt(2) опции SO_SNDBUF и SO_RCVBUF). А эти значения для TCP не могут превышать 64K. По умолчаниюю обычно от 8 до 16К. Но для send границей пакета является сам пакет. Т.е. как системе захотелось или удобней было его передать, так она и сделала. Поэтому изначально пользователю самому предлагается склеить их. Можно также в данном случае рекомендовать вызов write в блокирующем (ждущем) режиме, но и для него нужно предусмотреть прерывание выполнение (например пришедший сигнал для другого потока может прервать его выполенение). Если все же хочется использовать recv - то посмотри на флаг MSG_WAITALL.
я ни разу, ни разу, не повторяюсь, не повторяюсь :)
>я ни разу, ни разу, не повторяюсь, не повторяюсь :)
Понял спасибо всем, просто немного не с той стороны проблему смотрел, строго не судите, надеюсь не самый глупый вопрос...буду копать