Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Вниз

TserverSocet   Найти похожие ветки 

 
Fotog   (2003-04-13 21:53) [0]

Доброго времени суток Все
Если кто может объяснить толком как работать с TserverSocet в режиме stThreadBlocking


 
neodiX   (2003-04-14 01:20) [1]

Значит так:
в ОnGetSocket сервера пиши:
ClientSocket := TServerClientWinSocket.Create( Socket, ServеrSocket1.Socket );
в OnGetThread сервера так:
SocketThread := TServSockThread.Create( false, ClientSocket);


Описываешь поток:
TServSockThread = class(TServerClientThread)
private
SockStream : TWinSocketStream;
public
procedure ClientExecute; override;
end;


Главная процедура:
//*****************************************************************************
procedure TServSockThread.ClientExecute; //override;
var
RequestBuf,
ReplyBuf : string;
LenReceived : integer;
begin
SockStream := TWinSocketStream.Create( ClientSocket, 5000);
while (not Terminated) and ClientSocket.Connected do
begin
if SockStream.WaitForData(60*1000) then
begin
try
SetLength( RequestBuf, 1024 );
LenReceived := SockStream.Read( RequestBuf[1], Length(RequestBuf));
if LenReceived > 0 then
begin
SetLength( RequestBuf, LenReceived );
replybuf:="reply";
SockStream.Write( ReplyBuf[1], Length(ReplyBuf));
end
else BREAK; // клиент послал 0 байтов
except
BREAK; // stream read error, unexpected disconnect, ...
end;
end
else BREAK; // клиент не полслал данные в течении таймоута
end;
SockStream.Free;
SockStream := nil;
ClientSocket.Close;
end;


Ну вроде все, если что неработает - пиши.


 
Fotog   (2003-04-14 07:02) [2]

Спасибо огромное


 
Fotog   (2003-04-16 15:58) [3]

с сервером все понятно а как с клиентом
?


 
Nigger   (2003-05-07 01:24) [4]

Да кстати а кто-нибудь может объяснить как работает клиент с блокирующим режимом в нескольких сокетах? или это может только сервер?


 
Polevi   (2003-05-07 08:56) [5]

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


 
Digitman   (2003-05-07 09:18) [6]


> Nigger


С т.з. блокирующего/неблокирующего режима разницы нет никакой - будь то серверная сторона или клиентская. Здесь важно понять, что сам термин "блокирующий режим" означает лишь тот факт, что winsock-ф-ции (вызываемые в коде того или иного компонента), будучи вызванными, возвратят управление вызывающему коду либо после полного и успешного выполнения операции либо при возникновении некоей ошибки, не позволяющей успешное завершение операции.

Например, при блокирующем режиме метод ReceiveBuf(адрес_буфера, 10_байт), будучи вызванным в любом кодовом потоке, возвратит управление кодовому потоку только тогда, когда в указанный буфер будут приняты все 10 байт, запрошенных к приему. Т.е. дальнейшее выполнение программы в данном кодовом потоке будет блокировано до момента завершения работы метода. В случае же возникновения ошибки метод также возвратит управление вызывающему потоку, но - в возбуждением исключения (т.е. управление будет передано не на следующую после ReceiveBuf строчку, а в блок обработки исключения, если таковой предусмотрен алгоритмом).

При неблокирующем же режиме тот же метод ReceiveBuf(адрес_буфера, 10_байт), будучи вызванным в любом кодовом потоке, возвратит управление немедленно, в результате чего в указанный буфер будет записано ровно столько байт, сколько было фактически принято гнездом на момент вызова метода. Т.е. метод не блокирует дальнейшее выполнение программы в вызывающем кодовом потоке вплоть до доступности всех запрошенных к приему 10-ти байт (заранее же не известно, сколько времени потребуется на прием всех 10-ти байт, это может быть и доля секунды, и 5 минут и сутки), а тут же завершается, вернув ровно столько байт, сколько было доступно на момент вызова (от 0 и вплоть до 10-ти запрошенных байт). Если же во внутреннем буфере приема (после прочтения требуемых в дан. момент 10-ти байт) доступны данные размером сверх уже прочитанного в тек.вызове ReceiveBuf(), то будет немедленно возбуждено событие OnRead(), извещающее об этом факте. Когда кодовый поток, немедленно получивший управление после немедленного завершения метода ReceiveBuf, обработает полученную "порцию" данных, будет вызван обработчик события OnRead, в котором можно будет вновь вызвать ReceiveBuf, немедленно считать очередную доступную "порцию", быстро обработать ее (или передать на обработку другому код.потоку) и - вновь ждать события OnRead().


 
Andrey K.   (2003-05-07 12:04) [7]

>Digitman

Не совсем так.
При блокирующем режиме метод ReceiveBuf(адрес_буфера, 10_байт) (который, кстати, в хелпе рекомендуется использовать только в неблокирующем режиме) вернет управление сразу, как только получит хотя-бы 1 байт. При этом он возвернет количество реально принятых байт. Только если в буфере ничего пока нет, он будет ждать и соответственно блокировать поток.


 
Nigger   (2003-05-07 12:28) [8]

То есть можно использовать сервер как клиент для подключения к другому серверу и будет все нормально работать?


 
Nigger   (2003-05-07 12:36) [9]

И я вообще с трудом понимаю как реализовывается обмен данными при неблокирующем режиме.... вот например если на сервер послано 2 пакета-запроса то он ответит только на последний? Или как он отреагирует на принятие двух одинаковых пакетов при неблокирующем режиме(сразу один после другого)???
И еще я не понимаю как функции Recv и receiveln понимают при BlockingThread из какого сокета записывать данные... или они это делают автоматически по умолчанию (то есть привязываютя к данному сокету)???


 
Digitman   (2003-05-07 13:10) [10]


> Andrey K.


Да, ты прав. Это я загнул. В любом случае будет возвращен фактически доступный и принятый размер.


> Nigger


Да выбрось ты из головы на время свои "сервер" да "клиент" !
Речь идет о гнезде как таковом. И неважно, на какой стороне оно создано - на серверной или на клиентской. У каждого из гнезд на каждой из сторон есть методы приема и методы передачи.

Вчитайся вот в это (фрагмент хэлпа) :

For byte stream style socket (for example, type SOCK_STREAM), as much information as is currently available up to the size of the buffer supplied is returned.

If no incoming data is available at the socket, the recv call waits for data to arrive unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK

Это - описание ф-ции recv(). Ф-ция сия вызывается "внутри" кода компонента TCustomWinSocket, который используется Борландом в качестве универсального транспортного гнездового объета как на серверной , так и на клиентской стороне. И где ты в этом описании визишь хоть какое-либо упоминание о том, на какой из сторон (серверной или клиентской) должна вызываться эта ф-ция ? Речь идет лишь о различиях работы ф-ции в блок. и неблок. режимах.


 
Nigger   (2003-05-07 23:03) [11]

2Digitman: Ладно спасибо, с этим все ясно... а как насчет других вопросов?


 
Digitman   (2003-05-08 08:26) [12]


> Nigger



> например если на сервер послано 2 пакета-запроса то он ответит
> только на последний ?


Опять же - причем здесь сервер ? после установления соединения между приложением-сервером и приложением-клиентом на каждой из сторон существует по одному (индивидуальному для данного соединения) гнезду. Гнезда эти связаны в т.н. "виртуальную петлю соединения" (virtual circuit) и совершенно равноправны по реализованным в них механизмам приема-передачи - каждое из гнезд имеет одинаковые функц.методы приема и передачи (см. TCustomWinSocket). При этом в ходе инф.обмена по установленному "каналу связи" в каждый момент времени любая из сторон вольна использовать свое гнездо либо для приема либо для передачи (определяется Протоколом Инф.Обмена - ПИО - и алгоритмом, его реализующим). Если в соответствии с ПИО (разработанным тобой самим) одна из сторон последовательно посылает 2 инф.сообщения размером, скажем, 5 и 10 байт каждое, то другая сторона должна знать об этом и ожидать/принимать от посылающей стороны сначала первые 5 байт, затем следующие 10 байт. В конечном итоге принимающая сторона получает эти суммарные 15 байт в виде некоего непрерывного потока принимаемой инф-ции, из которого, в соответствии с ПИО, она должна считывать последовательно порции данных заведомо известного размера (5 байт и 10 байт). Последовательность выборки порций из принимаемого потока на принимающей стороне в точности соответствует последовательности записи этих порций в передаваемый поток на передающей стороне.



 
Digitman   (2003-05-08 08:47) [13]


> как он отреагирует на принятие двух одинаковых пакетов при
> неблокирующем режиме(сразу один после другого)?


реакция сервера определяется ТОЛЬКО твоим алгоритмом и никем/ничем более ! неблокирующий ли, блокирующий ли режим используется при этом - совершенно безразлично, это из иной оперы.

при неблокирующем режиме в моменты фактической доступности очер.порции данных во входящем потоке (читай - факт ненулевого размера входящего потока) будут возникать события OnRead()

Предположим, ожидаешь ты первые 5 байт (размер некоего запроса или ответа, посылаемого другой стороной)
Возникло событие OnRead, в его обработчике пытаешься прочитать из потока эти 5 байт, в результате прочитано 3 байта. Сколько осталось ? 2 байта. Занимаешься другим делом, а когда вход.поток вновь наполнится, вновь возникнет OnRead, где будешь пытаться прочитать оставшиеся 2 байта. Получил наконец-то все 5 байт ? Проверяй корректность их содержимого и обрабатывай полученное инф.сообщение нужным тебе образом. Еще не получил ? Продолжай заниматься своими делами, очередной OnRead известит тебя о том, что пожно пытаться "дочитать" недостающее. И так далее ...

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


> я не понимаю как функции Recv и receiveln понимают при BlockingThread
> из какого сокета записывать данные


Класс TServerClientThread (и его наследники) имеет паблик-свойство ClientSocket: TServerClientWinSocket. Это ссылка на объект-гнездо, которое участвует в вирт.соединении с конкретным активным клиентом (клиентским гнездом на другой стороне активного соединения). Вызывая в методе TServerClientThread.ClientExecute методы приема-передачи гнезда ClientSocket, ты тем самым осуществляешь инф.обмен с клиентом, ассоциированным в данный момент с данным кодовым потоком


 
Nigger   (2003-05-08 14:55) [14]

Спасибо... будем дальше разбираться...


 
Nigger   (2003-05-09 19:02) [15]

Че то вот ещё че не пойму.... Помоему я где-то я это упуслил.... вообщим создаю нить(от класса TThread), а в ней обработку соединения с TcpClient"ом... проверяю...работает только первая нить, и то помоему в ней только работают функции Open и Close(без разницы какой я режим использую блокирующий или нет)... или я перепутал или где-то я видел, что все что выше рабоет только под классом TClientServerThread... На WinSock это кстати работает... помогите разобраться! Если надо могу код привести.


 
Digitman   (2003-05-12 09:16) [16]

Белиберда какая-то).. Ничего не понятно.
Приводи код


 
panov   (2003-05-12 11:10) [17]

>Nigger

Создавай свою ветку и пиши вопросы там.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.009 c
1-55515
Poirot
2003-07-04 10:36
2003.07.17
Проблема с хранением больших числовых массивов


1-55594
Брат
2003-07-03 12:13
2003.07.17
Как вызвать ошибку EOverFlow?


3-55447
Ann
2003-06-24 09:09
2003.07.17
FastReport


14-55778
tipman
2003-06-29 20:36
2003.07.17
File Of PChar - глюк системы, компилятора или........?!


3-55476
caesar
2003-06-25 17:01
2003.07.17
DBLookupListBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский