Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.11.2012, 17:19   #1
TreadProblem
Пользователь
 
Регистрация: 07.03.2010
Сообщений: 12
По умолчанию Winsock , обрезает вывод

Возможно уже поднималась данная тема. Пишу прокси-тоннель через php гейт. Слушаю сокет на порту 3128 , получаю от браузера хэдер, разбираю его и по средствам idHTTP (изначально пробовал синапс и чистые сокеты) получаю строку типа string и отправляю ее обратно браузеру.

Возникает 2 проблемы.
1. Некоторые сайты не грузятся, грузится только присланный хэдер, а сам контент почему то не отображается, хотя в переменной S (сюда приходит ответ от гейта) все есть.
2. Вылетают invalid pointer value и AV , после того как ввел критические секции, вместо этой ошибки прога просто зависает. Видимо где то поток виснет и следующий поток уже не может добраться до кода, где происходило AV , так же в отладчике видно, что AV происходит в работе функции DeleteFree

кусок кода, где я предполагаю ошибки:
Код:
//тут мы проверяем запрос от браузера
          while 1 =1 Do begin
            FD_ZERO(fset);
            FD_SET(recvsock,fset);
            FD_SET(tunnelsock,fset);
            if select(0,@fset,nil,nil,nil) <> SOCKET_ERROR Then begin            
              if FD_ISSET(recvsock,fset) THEN begin 
                ZeroMemory(@buffer,sizeof(buffer));
                recv_len := recv(recvsock, buffer,sizeof(buffer),0);
                if recv_len = SOCKET_ERROR Then begin
           
                   break; 
                end;

                str:=pchar(@buffer);
                if pos('Host',str)<>0 then begin
                cs.Enter;
                re:=TRegExpr.Create;
                re2:=TRegExpr.Create;
                re3:=TRegExpr.Create;
                re4:=TRegExpr.Create;
                re.Expression:='Host:(.*?)\n';
                re2.Expression:='(.*?)\n\r';
                re3.Expression:='\n\r(.*?)$';
                re4.Expression:='\/(.*?)H';
                if re.Exec(str) then begin

                  re2.Exec(str);
                  re3.Exec(str);
                  re4.Exec(str);
                  http1:=TIdHTTP.Create(nil);
                  params:=TStringList.Create;
                  params.Add('h='+trim(re.Match[1])+'/'+trim(re4.Match[1]));
                  params.Add('&data='+trim(re3.Match[1]));
                  params.Add('&header='+trim(re2.Match[1]));
                  s:=HTTP1.POST('http://site.ru/p.php',params);
                  //form1.Memo1.lines.add(inttostr(length(s)));
                  CopyMemory(@Result, @s[1], (length(s) + 1) * SizeOf(Char));
                  send(recvsock,Result,sizeof(Result),0);
                  params.Free;

                  Http1.Free;
                  
                end;

                re.Free;
                re2.Free;
                re3.Free;
                re4.Free;
                cs.leave;
                end;

              end;
            end;
TreadProblem вне форума Ответить с цитированием
Старый 15.11.2012, 12:09   #2
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Код:
recv_len := recv(recvsock, buffer,sizeof(buffer),0);
if recv_len = SOCKET_ERROR Then begin
  break; 
end;
А если recv_len <> SOCKET_ERROR, то на основании чего ты решил что приняты все ожидаемые данные ?

Код:
send(recvsock,Result,sizeof(Result),0);
Кто такой "Result" ?
На оновании чего ты уверен что все sizeof(Result) байт данных успешно отправлены ?
xoodoo вне форума Ответить с цитированием
Старый 15.11.2012, 13:43   #3
TreadProblem
Пользователь
 
Регистрация: 07.03.2010
Сообщений: 12
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
Код:
recv_len := recv(recvsock, buffer,sizeof(buffer),0);
if recv_len = SOCKET_ERROR Then begin
  break; 
end;
А если recv_len <> SOCKET_ERROR, то на основании чего ты решил что приняты все ожидаемые данные ?

Код:
send(recvsock,Result,sizeof(Result),0);
Кто такой "Result" ?
На оновании чего ты уверен что все sizeof(Result) байт данных успешно отправлены ?
Первое пока не особо важно) , а второе это массив char
TreadProblem вне форума Ответить с цитированием
Старый 15.11.2012, 15:26   #4
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
Первое пока не особо важно
Как это "не особо", что за глупости ?
Следом за recv() ты начинаешь парсить контент запроса в расчете на то что он получен в объеме, достаточном для извлечения нужной тебе инф-ции.
А на самом деле получен лишь фрагмент контента.

Цитата:
второе это массив char
И на основании чего ты уверен что он будет передан полностью за один вызов send() ?
xoodoo вне форума Ответить с цитированием
Старый 15.11.2012, 21:09   #5
TreadProblem
Пользователь
 
Регистрация: 07.03.2010
Сообщений: 12
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
Как это "не особо", что за глупости ?
Следом за recv() ты начинаешь парсить контент запроса в расчете на то что он получен в объеме, достаточном для извлечения нужной тебе инф-ции.
А на самом деле получен лишь фрагмент контента.



И на основании чего ты уверен что он будет передан полностью за один вызов send() ?
1. целостность полученного запроса от браузера я постоянно проверяю визуально.
2. он должен передаться полностью, т.к. другие сайты в этом же объеме передаются нормально. а например 2ip.ru передается только хэдер, а именно сам контент отрезается. если убрать хэдер весь контент передается успешно, но в виде текста.
TreadProblem вне форума Ответить с цитированием
Старый 15.11.2012, 22:54   #6
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

по п.2 - полный бред.

Ок, спрошу иначе:

Cчитаешь ли ты полными идиотами разработчиков из Майкрософт, которые опубликовали в официальной документации к ф-ции winsock.recv следующее:

Цитата:
If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
xoodoo вне форума Ответить с цитированием
Старый 16.11.2012, 00:07   #7
TreadProblem
Пользователь
 
Регистрация: 07.03.2010
Сообщений: 12
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
по п.2 - полный бред.

Ок, спрошу иначе:

Cчитаешь ли ты полными идиотами разработчиков из Майкрософт, которые опубликовали в официальной документации к ф-ции winsock.recv следующее:
recv (тот запрос , что делает браузер) я постоянно проверяю визуально, я же написал. а вот send(recvsock,Result,sizeof(Result) ,0); отправляет то , что получено с php гейта, а не с recv . и почему то ya.ru он отправляет правильно, а 2ip отправляет только хэдер, причем игнорирует сам контент, который там имеется.

Я проводил эксперемент, брал контент страницы ya.ru и 2ip.ru загонял их в текстовики и поочередно отправлял через send , тоже самое.

п.с. я прекрасно понимаю, что считывать recv нужно до момента пока он не будет возвращать 0. Но я пытался отправить браузеру данные напрямую, чистым текстом. выходят вот такие дела.

Последний раз редактировалось TreadProblem; 16.11.2012 в 03:05.
TreadProblem вне форума Ответить с цитированием
Старый 16.11.2012, 12:40   #8
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
запрос , что делает браузер) я постоянно проверяю визуально
Да по барабану что ты там "проверяешь визуально" !

Нет никакой гарантии что твой один-единственный recv()-вызов при иных сетевых условиях получит запрос от браузера целиком.

И с send() та же песня - нет никакой гарантии что весь контент, требуемый к передаче, будет успешно отправлен за один-единственный вызов send().

На то тебе функция send() и возвращает результат, чтобы ты его анализировал с целью принятия дальнейшего решения, а не отправлял прямиком в мусор.

И почему-то флаг FD_READ ты проверяешь select'ом перед чтением из сокета, а опросить FD_WRITE перед записью в сокет не удосуживаешься, полагаясь неизвестно на что.

Последний раз редактировалось xoodoo; 16.11.2012 в 12:55.
xoodoo вне форума Ответить с цитированием
Старый 28.11.2012, 15:00   #9
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

В архиве консольный мини прокси
Допили этот проект, проще некуда...
или назови прокси сам допелю
Вложения
Тип файла: rar proxy.rar (7.5 Кб, 15 просмотров)
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 28.11.2012 в 15:05.
Slym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проигрыватель KMPLAyer при уменьшении окна проигрывателя обрезает видео,как убрать? kilogram Операционные системы общие вопросы 1 18.03.2012 02:36
Winsock n3sh C/C++ Сетевое программирование 2 25.07.2010 17:55
при изменении разрешения картинки , BitBlt обрезает её.. Человек_Борща Общие вопросы Delphi 2 29.04.2010 22:50
tomcat обрезает страницы antoliy Java для Web (EE, Servlet, JSP, Tomcat, Spring MVC) 7 15.12.2009 12:29