Получение данных через сокет, используя Synapse

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Получение данных через сокет, используя Synapse

Сообщение hrustbb » 24.05.2015 19:27:23

Добрый день.
Я пишу небольшой прокси на free pascal, используя synapse. Возникла проблемма следующего плана:
В коде после установки соединения и авторизации клиента работает следующий участок кода:

Код: Выделить всё
//получаем данные от клинта
rec_packet:=Self.ConnectionSocket.RecvPacket(120000);
str_stream:=TStringStream.Create(rec_packet);

//отправляем данные в интернет       
tcp.SendStreamRaw(str_stream);
str_stream.Destroy(); str_stream:=nil;
               
//получаем ответ из интернета
rec_packet:=tcp.RecvPacket(120000);
sleep(100); //вот без этого данные приходят не полностью, если их много!!!

//отправляем ответ клиенту
str_stream:=TStringStream.Create(rec_packet);
Self.ConnectionSocket.SendStreamRaw(str_stream);
str_stream.Destroy(); str_stream:=nil;


Вот почему после rec_packet:=tcp.RecvPacket(120000); нужно немного подождать sleep(100); чтобы получить данные полностью ?
hrustbb
незнакомец
 
Сообщения: 8
Зарегистрирован: 24.03.2015 18:08:08

Re: Получение данных через сокет, используя Synapse

Сообщение Pavia » 24.05.2015 20:24:44

hrustbb писал(а):Вот почему после rec_packet:=tcp.RecvPacket(120000); нужно немного подождать sleep(100); чтобы получить данные полностью ?

Потому что так устроенна сеть. RecvPacket - не блокирует компьютер что бы дождаться приема данных а возвращает то что пришло. На текущий момент вызова.
Так как TCP соединение это потоковое соединение, а не пакетное. То и обрабатывать его надо как поток.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Получение данных через сокет, используя Synapse

Сообщение hrustbb » 24.05.2015 21:02:08

А можно узнать что данные все получены? Что-то типа:
Код: Выделить всё
rec_packet:=tcp.RecvPacket(120000);
while not(tcp.WaitingData = 0) do;

Или узнать что пришли новые данные
hrustbb
незнакомец
 
Сообщения: 8
Зарегистрирован: 24.03.2015 18:08:08

Re: Получение данных через сокет, используя Synapse

Сообщение Pavia » 24.05.2015 21:29:20

hrustbb писал(а):А можно узнать что данные все получены? Что-то типа:

Поток не имеет конца и нельзя остановить. Поэтому узнать не получиться. Поток может только прерваться если произойдет разрыв соединения. Или если отправитель решит сам приостановить поток - остановить временно отправку данных.

Вы должны обрабатывать данные порциями. Когда вы пишите tcp.RecvPacket(120000); - вы сообщаете система максимальный размер порции которую вы можете обработать за один шаг.
Вы можете обрабатывать сообщениями.
На OnReadFilter вешаете ваш обработчик. Как только данные придут в систему так она вызывать вашу функцию. Можете считать что она крутиться в цикле. По аналогии с таймером.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Получение данных через сокет, используя Synapse

Сообщение hrustbb » 25.05.2015 20:03:33

Ничего не понимаю что-то:
Код: Выделить всё
//вешаем обрботчик на прием данных из интеренета
Self.tcp.OnReadFilter:=@Self.OnReadFilterTCP;
//вешаем обработчик на прием от клиента
Self.ConnectionSocket.OnReadFilter:=@Self.OnReadFilterClient;
//ждем данные из интернета
Self.tcp.RecvPacket(120000);
//ждем данные от клиента
Self.ConnectionSocket.RecvPacket(120000);

Собственно обработчики
Код: Выделить всё
procedure CProxyThread.OnReadFilterTCP(Sender: TObject; var Value: AnsiString);
var str_stream:TStringStream;
    sock:TTCPBlockSocket;
begin
  //пришли данные из интернета
  str_stream:=TStringStream.Create(Value);
  //Отправляем их клиенту
  Self.ConnectionSocket.SendStreamRaw(str_stream);
  //ждем новых данных
  sock:=TTCPBlockSocket(Sender);
  sock.RecvPacket(120000);
end;


Код: Выделить всё
procedure CProxyThread.OnReadFilterClient(Sender: TObject; var Value: AnsiString);
var str_stream:TStringStream;
    sock:TTCPBlockSocket;
begin
  //пришли данные от клиента
  str_stream:=TStringStream.Create(Value);
  //шлем их в интернет
  Self.tcp.SendStreamRaw(str_stream);
  //ждем новых данных
  sock:=TTCPBlockSocket(Sender);
  sock.RecvPacket(120000);
end;


И... не работает. Подключаюсь браузером через свой прокси используя proxychains, в браузере пишет Соединение... и все. При этом если в procedure CProxyThread.OnReadFilterClient(Sender: TObject; var Value: AnsiString); убрать
Код: Выделить всё
  //ждем новых данных
  sock:=TTCPBlockSocket(Sender);
  sock.RecvPacket(120000);

то в принципе все так же, но после того как вырубаю свой прокси браузер кое что да отобразит.
Что не так? Не доходит
hrustbb
незнакомец
 
Сообщения: 8
Зарегистрирован: 24.03.2015 18:08:08

Re: Получение данных через сокет, используя Synapse

Сообщение hrustbb » 31.05.2015 16:30:40

Я готов заплатить за решение данной проблеммы

Добавлено спустя 3 часа 13 минут 44 секунды:
неужели невыполнимо?

Добавлено спустя 2 часа 26 минут 56 секунд:
переделал https://yadi.sk/d/Ad1t4IBhgyqBc теперь мой прокси сервер успешно передает запрос клиента серверу, получает ответ от удаленного сервера отсылает ответ клиенту, а клиент его не принимает
hrustbb
незнакомец
 
Сообщения: 8
Зарегистрирован: 24.03.2015 18:08:08


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru