Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты в Дельфи !!! 
:(
    Опции темы
Vinnety
  Дата 5.10.2004, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 8.4.2003

Репутация: нет
Всего: нет



qstn.gif Народ! Помогите советом!
Мне необходимо передать посредством сокетов с клиентской программы (использую TClientSocket) данные на программу-сервер(использую TServerSocket).

Вопрос №1. Как мне на стороне сервера (используя TServerSocket) определять адреса клиентов, т.е. чтобы я мог послать определенную информацию определённому пользователю.
Например, чтобы сообщение "Привет, Коля!" дошло Коле, а не кому то другому.

Вопрос №2. Мне необходимо передавать данные :

type
TPack = record
Code : integer;
Data : double;
end;
TArrRec = array of TRec;

TRec = record
UserID : integer;
ActionID : integer;
Datas : TArrRec;
end;

var
Rec : TRec;


Т.е. массив TArrRec - динамический, поля UserID, ActionID - служебные (для передачи на данных на сервер).
Как мне отправить наполнить и отправить такую запись как Rec через сокеты (используя TClientSocket)? Каким способом лучше это сделать (через SendBuf или SendStream)?
Или кто-то видит другое решение проблемы?

PM MAIL   Вверх
Alex
Дата 5.10.2004, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 4
Всего: 162



В Delphi документации по многопотоковому TServerSocket налито довольно много воды, и начинающему программисту сложно понять суть дела. Давайте попытаемся пролить немного света на этот раздел хелпа.

Совместимость: Delphi 3.x (или выше)

Вообще-то, создать многопотоковый сервер, который ожидает пришедшие сообщения на сокете довольно просто. В Delphi для этой цели достаточно использовать компонент TServerSocket.

Давайте рассмотрим структуру работы данного компонента:

- Добавляем TServerSocket в Вашу основную форму.
- Устанавливаем свойство Servertype в stThreadBlocking
- Создаём новый "unit" (показанный ниже) содержащий поток сервера.


Устанавливаем следующий код на OnSocketGetThread

Код
procedure TfrmMain.fSocketGetThread(Sender: TObject;  
 ClientSocket: TServerClientWinSocket;  
 var SocketThread: TServerClientThread);  
begin  
 // Здесь создаём объект TServerThread, который я привожу ниже.  
 // Новый объект создаётся каждый раз, когда когда установлен канал связи.  
 SocketThread := TServerThread.Create( FALSE, ClientSocket );  
end;  


TServerThread - это объект, который я создаю самостоятельно. Объект наследуется от TServerClientThread и содержит код, который обычно читает и пишет данные из/в сокет.

Созданный "unit", содержит следующий код:

Код
unit serverthread;  

interface  

uses  
 windows, scktcomp, SysUtils, Classes, Forms;  

type  
 EServerThread = class( Exception );  
 // serverthread это потомок TServerClientThread  
 TServerThread = class( TServerClientThread )  
   private  
     fSocketStream : TWinSocketStream;  
   public  
     procedure ClientExecute; override;  
     // ClientExecute отменяет  
     // TServerClientThread.ClientExecute  
     // и содержит код, который  
     // выполняется при старте потока  
 end;  

implementation  

procedure TServerThread.ClientExecute;  
begin  
 inherited FreeOnTerminate := TRUE;  
 try  
   fSocketStream := TWinSocketStream.Create( ClientSocket,  
                                             100000 );  
   // 100000 - это таймаут в миллисекундах.  
   try  
     while ( not Terminated ) and ( ClientSocket.Connected ) do  
     try  
       // В это место обычно помещается код,  
       // ожидающий входных данных, читающий из сокета или пишущий в него  
       // Пример, приведённый ниже, показывает, что можно добавить в данную  
       // секцию программы.  
     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;


Когда связь установлена, потоку необходимо ожидать входящих данных(запроса от клиента). Для этого можно использовать следующий код:

Код
if ( not Terminated ) and  
  ( not fSocketStream.WaitForData( 1000000 ) ) then  
begin  
 // Обработчик таймаута (т.е. если по истечении 1000000 миллисекунд
 // от клиента не пришло запроса
end;  
// В сокете есть входящие данные!  


Для чтения данных, Вам понадобится создать буфер для хранения полученных данных. Обычно буфер - это PByteArray или массив символов. В этом примере я обозвал буфер как fRequest который является массивом символов. Кроме того я ожидаю фиксированное количество байт. Массив имеет постоянный размер REQUESTSIZE.

Код
var  
 ac, readlen : integer;  
begin  
 FillChar( fRequest, REQUESTSIZE, 0 );  
 ac := 0;  
 repeat  
   readlen := fSocketStream.Read( fRequest[ac],  
                                  1024 );  
   // считываем блоки по 1024 байт, до тех пор, пока буфер  
   // не заполнится  
   ac := ac+readlen;  
 until ( readlen = 0 ) or ( ac = REQUESTSIZE );  
end;


Если readlen равно 0, значит больше нет входящих данных. Функция Чтения завершается через 100000 миллисекунд после запуска в TWinSocketStream.Create(). Если Вы не знаете сколько времени нужно ожидать запроса от клиента, то чем меньше будет таймаут, тем лучше. В большинстве случаев максимальный таймаут не должен превышать 30 секунд.

При посылке ответа, Вы должны знать, в каком режиме работает клиент. Многие клиенты ожидают только один пакет ответа, другие ожидают несколько пакетов. В этом примере, я подразумеваю клиента, который ожидает только один пакет, так что я должен послать мои данные назад в одном блоке:

Код
fSocketStream.WriteBuffer( fRep, fReplySize );  

fRep это буфер, содержащий ответ на запрос клиента, и fReplySize - это размер буфера.

Взято с Исходников.ru http://www.sources.ru
Добавлено @ 19:50
А вообще скачай Delphi Russian Knowledge Base и там найдешь еще информацию о сокетах и не только.

Это сообщение отредактировал(а) Alex - 5.10.2004, 19:48


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0825 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.