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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.09.2011, 05:26   #1
WennY
Форумчанин
 
Регистрация: 17.01.2008
Сообщений: 236
Радость Вернуть ответ браузеру (TTcpServer)

Доброго времени суток! Организую небольшой прокси-сервер на основе TTcpServer. Все хорошо, но не получается нормально выдать браузеру ответ серверных манипуляций. Реализация (вернее, её подобие) сего процесса располагается в самом низу нижевыложенного кода, ниже комментария "пытаемся вернуть ответ браузеру". Выдает что-то необъяснимое, ничего не имеющее общего с тем, что скапливается в переменной ResponseData. Подскажите, пожалуйста, что не так делаю

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Sockets, StdCtrls;

type
  TForm1 = class(TForm)
    TcpServer1: TTcpServer;
    TcpClient1: TTcpClient;
    Memo1: TMemo;
    procedure TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;

implementation

{$R *.dfm}

{ разрезание строк по разделителю }
procedure Explode(var a: array of string; Border, S: string);
var
  S2: string;
  i: Integer;
begin
  i := 0;
  S2 := S + Border;
  repeat
    try
      a[i] := Copy(S2, 0, Pos(Border, S2) - 1);
    except
    end;
    Delete(S2, 1, Length(a[i] + Border));
    Inc(i);
  until S2 = '';
end;

{ запись в файл }
function WriteFile(FileData : String; FileName : String) : Bool;
Var
  f:System.Text;
begin
  AssignFile(f, FileName);
  Append(f);
  Write(f, FileData);
  CloseFile(f);
end;

{ клиент }
function GetContent(Request : string) : string;
var
  s, Content: string;
  i, size: integer;
  P: pchar;
  RecLen: integer;
  TCPClient1: TTcpClient;
  Handle : HWND;
  A : array[0..2] of string;
  Host: string;
begin
  { парсим хост }
  Explode(A, #13#10, Request);
  Explode(A[0], ' ', Request);
  Host := StringReplace(A[1], 'http://', '', [rfIgnoreCase]);
  Host := StringReplace(Host, StrPos(PChar(Host), '/'), '', [rfIgnoreCase]);

  { настройки соединения }
  TCPClient1:=TTCPClient.Create(nil);
  TcpClient1.RemoteHost := Host;
  TcpClient1.RemotePort := '80';

  { препринимаем попытку соединения }
  if TcpClient1.Connect then
   begin

    { отправляем запрос }
    TcpClient1.SendLn(Request + #13#10#13#10);

    { выделяем память }
    P := GetMemory(256);

    { получаем ответ }
    RecLen := TcpClient1.ReceiveBuf(P^, 256);

    { обрабатываем все это дело }
    while RecLen > 0 do
      begin
         Content := Content + P;
         RecLen := TcpClient1.ReceiveBuf(P^, 256);
      end;

    { закрываем соединение }
    TcpClient1.Disconnect;

  end
  { если соединение не удалось }
  else MessageBox(Handle, 'Сервер не найден!', 'Error', 16);

  { убираемся }
  TcpClient1.Free;

  { вовращаем ответ }
  Result := Content;
end;

{ сервер }
procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
var
  s, ResponseData: string;
  r : pchar;
  Siz: integer;
begin
  { получаем заголовки запроса клиента }
  s:=ClientSocket.ReceiveLn;

  { отправляем запрос и получаем ответ }
  ResponseData := GetContent(s);

  { пытаемся вернуть ответ браузеру }
  s := Copy(ResponseData, 1, 256);
  Siz := ClientSocket.SendBuf(s, SizeOf(s) );
  while Siz>0 do begin
    Delete(ResponseData, 1, 256);
    s := Copy(ResponseData, 1, 256);
    Siz := ClientSocket.SendBuf(s, SizeOf(s) );
  end;

  { закрываем соединение }
  ClientSocket.Close;
end;

end.
Залил весь проект, если потребуется...
Вложения
Тип файла: rar problem_proxy.rar (1.8 Кб, 14 просмотров)

Последний раз редактировалось WennY; 06.09.2011 в 05:38.
WennY вне форума Ответить с цитированием
Старый 07.09.2011, 17:01   #2
WennY
Форумчанин
 
Регистрация: 17.01.2008
Сообщений: 236
По умолчанию

Причину, похоже, выяснил. При считыванияи буфера в конец каждой выделенной строки добавляется нечто, что в итоге гробит весь код. Например при коде TcpClient1.ReceiveBuf(P^, 256) (считывание по 256 байт) у меня будет запорот каждый 257 символ (т.е. он не заменяет, а именно добавляет символ в конец при каждом выделении указанного количества байт). Извлечь его не представляется возможным (во всяком случае я пока даже не могу понять, что это). Проблема, конечно, решается разовым выделением необходимого количества буфера для скачки всего контента одним махом, но хотелось бы понять, в чем причина и принимать данные все же по кускам.. Спасибо
WennY вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с компонентами TTcpClient, TTcpServer RADE Работа с сетью в Delphi 3 13.07.2011 11:59
Работа с TTcpClient,TTcpServer на Delphi 7 NaReeAl Работа с сетью в Delphi 3 05.09.2009 15:57
Ответ web-сервера браузеру - изображение TpyHT C/C++ Сетевое программирование 3 05.05.2009 22:34
TTcpServer и client JoanM Работа с сетью в Delphi 3 07.03.2008 17:23
TTcpServer и TUdpSocket блокируют порт hawk1 Работа с сетью в Delphi 5 07.12.2006 23:29