Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TSocketClient и TSocketServer работа с потоками


Страницы:   1 2 3

Vladimir ©   (2009-03-01 10:27:00) 

Доброго времени суток всем! Заранее извиняюсь если данная тема уже поднималась, но в поиске ответа на свой вопрос я так и не нашел. Требуется написать клиент-серверное приложение. В данный момент написал пробные клиент и сервер на SocketClient и SocketServer соответсвенно работающие в синхронном режиме. Подскажите пожалуйста каким образом  организовать их работу в асинхронном режиме, чтобы сервер одновременно обслуживал несколько клиентов! И ещё есть такая проблема при посылке текста через SendText на сервер приходят иероглифы, причем  это только на Windows Vista, на Windows XP все работало нормально. Использую Delphi 2009. Из-за чего это может быть? Заранее спасибо.


Сергей М.   (2009-04-29 09:16:00) [21]


> inherited FreeOnTerminate := TRUE;


Это убрать.


> FillChar( fRequest, REQUESTSIZE, 0 );


Чемув этот момент равно значение переменной REQUESTSIZE ?


> Terminate;


Это тоже убрать.


> не понял как отправлять с клиента что-то на такойсервер


Т.е. на какой-то другой ты понял, а вот именно на этотне понял ?


Zalm   (2009-04-29 02:05:00) [22]

Вот попытался собрать то что указано по ссылке
http://www.delphisources.ru/pages/faq/base/tserversocket.html
но ничего не получилось, выдает ошибки памяти.

procedure TForm1.ServerGetThread(Sender: TObject;
 ClientSocket: TServerClientWinSocket;
 var SocketThread: TServerClientThread);
begin
 SocketThread := CServerThread.Create( FALSE, ClientSocket );
end;

Procedure CServerThread.ClientExecute;
var
REQUESTSIZE : integer;
fRequest : array [0..1024] of char;
ac,readlen : integer;
begin
 inherited FreeOnTerminate := TRUE;
 try
   fSocketStream := TWinSocketStream.Create( ClientSocket, 1000 );
   // 100000 - это таймаут в миллисекундах.
   try
     while ( not Terminated ) and ( ClientSocket.Connected ) do
       try
         // В это место обычно помещается код,
         // ожидающий входных данных, читающий из сокета или пишущий в него
         // Пример, приведённый ниже, показывает, что можно добавить в данную
         // секцию программы.
          FillChar( fRequest, REQUESTSIZE, 0 );
          ac := 0;
          repeat
           readlen := fSocketStream.read( fRequest[ac], 1024 );
           // считываем блоки по 1024 байт, до тех пор, пока буфер
           // не заполнится
           ac := ac+readlen;
          until
          (readlen = 0) or (ac = REQUESTSIZE);
       except
         on e:exception do
         begin
           // Если произошла ошибка, то закрываем сокет и выходим
           ClientSocket.Close;
           Terminate;
         end;
       end;
   finally
     fSocketStream.Free;
   end;
 except
   on e:exception do
   begin
     // Если произошла ошибка, то закрываем сокет и выходим
     ClientSocket.Close;
     Terminate;
   end;
 end;
end;


Еще не понял как отправлять с клиента что-то на такой сервер...
Помогите пожалуйста


Сергей М.   (2009-03-13 20:55:00) [23]


> часть отправки данных пишеться в событиях клиента


Каких конкретно ?


Тын-Дын   (2009-03-13 00:16:00) [24]


> Vladimir   (12.03.09 22:01) [27]


Раз у тебя Borland-сокеты работают в режиме st/ctBlockinkg, то и используй их возможности для обработки входящих данных.


Vladimir   (2009-03-12 22:01:00) [25]

Нет) просто немного напрягает когда часть отправки данных пишеться в событиях клиента, а часть приема данных пишеться "где-то" причем ручками. Не знаю почему, но есть какое-то чувство, что то что я сам дописал возьмет и не сработает. Вот и ответ на вопрос "сошелся ли свет клином на событиях")


Сергей М.   (2009-03-12 21:22:00) [26]


> что же делать?


А что, на событиях свет клином сошелся ?


Vladimir   (2009-03-12 20:59:00) [27]

И что же делать? Оставить тот вариант который я уже реализовал? Вроде он рабочий...


Сергей М.   (2009-03-09 15:00:00) [28]


> ClientSocket должен автоматически входить в событие Read
> когда к нему приходят данные


Нет, не должен.
Событие OnRead возбуждается только при условии ClientType = ctNonBlocking, а у тебя ctBlocking


Vladimir   (2009-03-08 10:26:00) [29]

С критическими секциями разобрался. Все ок. Но возникла новая проблема. ClientSocket должен автоматически входить в событие Read когда к нему приходят данные от сервера, но он почему то этого не делает. Пришлось сделать следующее. Создать глобальную переменную RegSocket: TWinSocketStream и на событие Connect клиента(RegClient) поставил следующий код RegSocket := TWinSocketStream.Create(Socket, 60000);

А в том месте, где необходимо получить ответ от сервера поставил следующий код

while not RegSocket.WaitForData(100) do
Application.ProcessMessages;
RegClient.OnRead(Sender, RegClient.Socket);

То есть вручную проверяю пришли ли данные от сервера и если пришли, то вызываю процедуру Read клиента. Хотя по идеи клиент сам должен понять что сервер послал ему данные и сам войти в событие Read. В чем может быть дело?


Vladimir   (2009-03-04 11:13:00) [30]

спасибо Сергей. Буду вспоминать и разбираться.


Сергей М.   (2009-03-04 11:05:00) [31]


> помнилось что можно как то секцию кода блокировать или может
> быть называеться это как то по другому


Вот как раз "критической секцией" это и называется.


Vladimir   (2009-03-04 10:43:00) [32]


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


Хорошо, спасибо, это я сделаю. Но мне помнилось что можно как то секцию кода блокировать или может быть называеться это как то по другому. Просто давно как то писал простенький многопоточный чат и там тоже  необходимо было предотвратить одновременное обращение как к файлу, так и к общим переменным. Исходников того чата не осталось и как именно прописывал это не помню.


Сергей М.   (2009-03-04 10:22:00) [33]

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


Vladimir   (2009-03-04 10:14:00) [34]


> Или ты валишь данные прямо в файл, называя при этом "базой
> данных" именно этот файл ?


В чем то ты прав. СУБД я не использую, но и не валю все прямо в файл(есть некая структура)... но, думаю что сейчас объяснять все в подробностях ни к чему.


Сергей М.   (2009-03-04 09:45:00) [35]


> нет, файл базы данных


И какая СУБД при этом тобой используется ?
Или ты валишь данные прямо в файл, называя при этом "базой данных" именно этот файл ?


Vladimir   (2009-03-04 09:06:00) [36]


> Уж не файл ли протокола ?

нет, файл базы данных


> Для этого придуманы объекты синхронизации и доступ к файлу
> в режиме ShareDenyNone

я знаю... но хотел узнать нельзя ли каким то образом блокировать секцию кода, до тех пор пока она не будет выполнена... сделать что то вроде:

Lock;
выполняемый операции
UnLock;

чтобы если какой то поток уже начал обрабатывать этот участок кода, то другому потоку пришлось ждать пока первый закончит с ним работать.


medved_68   (2009-03-04 08:56:00) [37]


> Как "объяснить" компьютеру  подождать пока один поток поработает
> с файлом и только потом самому приступать к работе с ним?
>

Для этого придуманы объекты синхронизации и доступ к файлу в режиме ShareDenyNone


Сергей М.   (2009-03-03 20:46:00) [38]


> процедура которая работает с файлом(записывает в него данные)
> и закрывает файл


Уж не файл ли протокола ?


Vladimir   (2009-03-03 20:31:00) [39]

Спасибо, все получилось. Только появился ещё один вопрос. Когда клиент присоединяеться к серверу для него создаеться отдельный поток, а из потока вызываеться некая процедура которая работает с файлом(записывает в него данные) и закрывает файл... Дело в том что если сервер работает не в многопоточном режиме, то проблемы одновременного обращения к файлу не возникает, а как быть при моем раскладе с потоками? Как "объяснить" компьютеру  подождать пока один поток поработает с файлом и только потом самому приступать к работе с ним?


Vladimir   (2009-03-03 13:46:00) [40]

спасибо, попробую.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо