Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 22.06.2009, 20:09
Аватар для Agito
Agito Agito вне форума
Прохожий
 
Регистрация: 22.06.2009
Сообщения: 11
Репутация: 10
По умолчанию Передача файлов в чате

В общем стоит задача написать чат (написан почти что, писал на основе КлиентСокет и Скрвер) и сделать возможным передачу файлов. Нашел несколько исходников передачи файлов через Сокеты... все не работают, получилось какие-то починить . Но проблема встала следующая: при передаче файлов (метров например 700) форма вешается и сообщения до конца передачи файлов посылать нельзя будет ("будет" потому что я еще не встроил передачу файлов в чат). Нужно как-то замутить передачу в отдельном потоке, чтобы форма в это время не нагружалась. Поискал я что-то нечто подобное в разных разделах, найти ответ не удалось. Может кто-то сталкивался с подобной проблемой и имеется простенький исходник?
Ответить с цитированием
  #2  
Старый 22.06.2009, 20:36
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Если у тебя порции файлов передаются в цикле, то возможно хватит простого Application.ProcessMessages.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 22.06.2009, 21:48
Аватар для Agito
Agito Agito вне форума
Прохожий
 
Регистрация: 22.06.2009
Сообщения: 11
Репутация: 10
По умолчанию

Так, циклов нету, событие Ресив проихсдоит просто часто. Вот один исходник:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
  l: Integer;
  buf: PChar;
  src: TFileStream;
  pat: string;
begin
  pat:='hz.rar';
  l:= Socket.ReceiveLength;
  GetMem(buf,l+1);
  Socket.ReceiveBuf(buf[0],l);
  if fileexists(pat) then src:= TFileStream.Create(pat, fmopenreadwrite) else src:= TFileStream.Create(pat, fmCreate);
  src.Seek(0,soFromEnd);
  src.WriteBuffer(buf[0],l);
  src.Free;  
  FreeMem(buf);
end;

Есть второй вариант, там идет работа с TMemoryStream - работает лучше, тормозит только на сохранение файла, но данный вариант меня не устраивает.

Последний раз редактировалось Agito, 22.06.2009 в 21:57.
Ответить с цитированием
  #4  
Старый 22.06.2009, 23:14
PiboDIE PiboDIE вне форума
Прохожий
 
Регистрация: 17.06.2009
Сообщения: 28
Репутация: 10
По умолчанию

Вероятность нахождения такого исходника невелика. Поэтому попробую подтолкнуть к одному из вариантов:
Нужно писать отдельный поток (это Вы уже определили) на передачу файла. Причем - гораздо выгоднее писать один поток для 2х действий (что бы не зависал клиент не только получателя но и отправителя) - передача и прием файлов, которые вызываться будут в зависимости от поступившей на основной сокет команды. Этот поток должен содержать свой сокет (или основной сокет переводить на режим совместимости с потоками. Давно не баловался - нюансов не помню).
В итоге должна быть примерно следующая схема:
1.При попытке отправить файл - стартует поток с задачей "отправить файл", порт сокета рекомендуется использовать отличный от "коммуникационного". Клиент-отправитель направляет по коммуникационному порту запро на принятие файла
2.Клиент-получатель при получении запроса на принятие файла стартует поток с задачей "получить файл" (в качестве параметров можно использовать ip адрес клиента-отправителя и порт). Далее уже поток направляет запрос о том, что "готов принять файл" и готовит сокет для принятия файла
3.Клиент-отправитель при получении запроса о принятии файла - "стартует" передачу.
В дополнение можно прикрутить кучу дополнительных плюшек в виде формы с отображением процесса передачи, проверка CRC по завершению передачи для фиксирования целостности файла, при нарушении CRC - повторная попытка передать файл и многое другое, чего душе угодно.
В общем, поскольку с сетями по всей видимости разобрались - достаточно почитать немного литературы об организации потоков. Так же хочу предупредить - локализация ошибок в потоках бывает довольно сложным занятием, будьте внимательны к мелочам.
Ответить с цитированием
  #5  
Старый 23.06.2009, 01:20
Аватар для Agito
Agito Agito вне форума
Прохожий
 
Регистрация: 22.06.2009
Сообщения: 11
Репутация: 10
По умолчанию

Эх, в том-то и дело, что я знаю, что нужно делать, но вот как... то есть у меня одна проблема - реализация, почитав про потоки понял лишь как простой кусок кода замутить в отдельном потоке, но событие так и не удалось выгрузить.
Ответить с цитированием
  #6  
Старый 23.06.2009, 09:15
PiboDIE PiboDIE вне форума
Прохожий
 
Регистрация: 17.06.2009
Сообщения: 28
Репутация: 10
По умолчанию

Цитата:
Сообщение от Agito
Эх, в том-то и дело, что я знаю, что нужно делать, но вот как... то есть у меня одна проблема - реализация, почитав про потоки понял лишь как простой кусок кода замутить в отдельном потоке, но событие так и не удалось выгрузить.
А что Вы подразумеваете под "выгрузить событие"
Если речь идет о передаче параметров потоку то тут возможен вариант создания своего конструктора потока (с нужными параметрами) или создание приостановленного потока, далее заполнение различных, необходимых для работы параметров и по завершению запуск потока.
Ответить с цитированием
  #7  
Старый 23.06.2009, 12:34
Аватар для Agito
Agito Agito вне форума
Прохожий
 
Регистрация: 22.06.2009
Сообщения: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от PiboDIE
А что Вы подразумеваете под "выгрузить событие"
Если речь идет о передаче параметров потоку то тут возможен вариант создания своего конструктора потока (с нужными параметрами) или создание приостановленного потока, далее заполнение различных, необходимых для работы параметров и по завершению запуск потока.
"выгрузить событие" - ошибся, надо было написать "вгрузить" . Смысл в том, что сначала создается поток, а уже потом в него засовывается событие "Ресив". С параметрами могут возникнуть проблемы, так как возможна разсинхронизация между "Ресив" и нашим потоком, то есть надо не через параметры... а конкретно прям все события засунуть в отдельный поток.
Ответить с цитированием
  #8  
Старый 23.06.2009, 13:11
PiboDIE PiboDIE вне форума
Прохожий
 
Регистрация: 17.06.2009
Сообщения: 28
Репутация: 10
По умолчанию

Цитата:
Сообщение от Agito
"выгрузить событие" - ошибся, надо было написать "вгрузить" . Смысл в том, что сначала создается поток, а уже потом в него засовывается событие "Ресив". С параметрами могут возникнуть проблемы, так как возможна разсинхронизация между "Ресив" и нашим потоком, то есть надо не через параметры... а конкретно прям все события засунуть в отдельный поток.
В потоке можно описывать свои методы так же как при описании какого-либо класса. Главное стоит помнить что код потока должен выполняться в рамках процедуры Execute, и уже там реализовывать поведение потока.
По поводу "вгрузить", как я и описал выше - можно создать свой конструктор (тот, который Create) с нужными параметрами и создавать поток с помощью этого конструктора, а можно создавать приостановленный поток стандартным конструктором, передавать ему параметры и запускать выполнение потока.
Не очень понятно какой именно рассинхронизации Вы опасаетесь, опишите подробнее пожалуйста.
Ответить с цитированием
  #9  
Старый 25.06.2009, 00:14
Аватар для Agito
Agito Agito вне форума
Прохожий
 
Регистрация: 22.06.2009
Сообщения: 11
Репутация: 10
По умолчанию

В общем замутил с TMemoryStream, из-за того, что время поджимало очень сильно, всем спасибо, хоть мы ни к чему и не пришли .
Ответить с цитированием
Ответ


Delphi Sources

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

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:54.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025