![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Sockets [D6, WinXP]
dkDimon © (2002-11-04 14:48:00)МОжет кто-нибудь привести примерчик передачи и принятия буфера в TClientSocket & TServerSocket (SendBuf, ReceiveBuf) записей (record). Ну или скажите что я делаю неправильно:
Клиент:
type
TSendInfo = packed record
Cmd: String;
Data: Pointer;
end;
...
procedure Send;
var
si: TSendInfo;
begin
si.Cmd := "Command";
si.Data := ... (чему-нибудь);
ClientSocket.Socket.SendBuf(si, SizeOf(si));
end;
Сервер:
type
TSendInfo = packed record
Cmd: String;
Data: Pointer;
end;
...
procedure Receive;
var
si: TSendInfo;
begin
ServerSocket.Socket.ReceiveBuf(si, ServerSocket.Socket.ReceiveLenth);
end;
ОШИБКА!!! Access violation...
Плиз, помогите кто чем может...
Sinplecy (2003-02-04 14:57:00) [1]Теперь понял. Спасибо!
Digitman (2003-02-04 09:02:00) [2]
> Sinplecy
> в случае получения разрешение на посылку данных от TServerSocket.
Почему же "от" ? "в" !!!
После установки вирт.петли соединения между двумя удал.партнерами (неважно кто из них сервер, а кто - клиент) у каждой из сторон есть по одному экз-ру "передатчика" и "приемника". И передача и прием используют внутреннюю буферизацию ввода/вывода, размеры этих буферов ограничены. Например, внутр.буфер передачи в большинстве тек.реализаций WSP имеет размер в умолчанию в 8кб. Попытка записи в этот буфер в неблок.режиме блока данных общим размером более 8кб (в один или несколько вызовов send-методов) вызовет отказ с кодом WSAEWOULDBLOCK, сигнализирующий о "занятости" буфера передачи невозможности в дан.момент поместить в него требуемый к передаче блок данных. Как только буфер освободится (читай - данные будут физически "вытолкнуты" в канал связи с партнером), WinSock сообщит об этом возбуждением событий OnWrite() (для клиента) и OnClirntWrite() (для сервера). Кр. того WinSock извещает этими событиями партнеров по обмену о незанятости из буферов передачи как минимум 1 раз - сразу же после установления вирт.петли коннекта (сразу же за событием On[Client]Connect).
Т.о., если используется неблок.режим и вызов одного из send-методов (на любой стороне вирт.соединения) дал отказ, сигнализирующий о недоступности в дан.момент буфера передачи, необходимо дождаться ближ.события On[Client]Write и повторить попытку записи в буфер передачи тем же send-методом, но указав в нем параметрами уже только ту часть данных (требуемых к передаче), которая на этот момент еще не была помещена в буфер из-за предыдущего отказа при вызове send-метода.
Sinplecy (2003-02-04 08:43:00) [3]OnWrite - событие, возникающее в TClientSocket в случае получения разрешение на посылку данных от TServerSocket.
Я так это понял.
На всякий случай еще раз слазал в help -
Occurs when a client socket should write information to the socket connection.
Digitman (2003-02-03 13:47:00) [4]
> Sinplecy
расскажи подробно, как ты себе представляешь логику возникновения и обработки события OnWrite()
Sinplecy (2003-02-03 13:05:00) [5]Удалено модератором
ole (2002-12-14 11:34:00) [6]На событие клиента OnConnect отправить данные:
SendBuf(Buf, SizeOf(Buf));
На сервере
1. при неблокирующем подключении:
OnClientRead
Socket.ReceiveBif(Buf,Socket.ReceiveLength);
2. при блокирующем подключении:
создать Thread по запросу сервера
(ClientExecute):
ClientSocket.ReceiveBuf и т.д.
или, что удобнее
создать TWinSocketStream
далее считывать из Stream"а, а можно и записывать в него.
все есть в хелпе Дельфов...
Sheriff (2002-12-11 10:20:00) [7]Если есть желание переслать всю запись сразу:
Bred = record
Cmd: Integer;
Status: Integer;
TimeSend: TTime;
Mess: String[255];
end;
если указать Mess: String; то Mess придется передавать отдельно.
Danlicha (2002-12-10 17:36:00) [8]:)
CyANiD (2002-12-10 14:54:00) [9]Вообще у меня не получаеться пересылать буфер, если server и client - разные проги. Если это все в одной проге, то проблем нет. Да и тип (record) посылаемого сообщения должен быть аналогичен принимаемому... Подумай на эту тему, если ничего не приходит в голову, то пиши на mail мне, пришлу тебе исходники
Reindeer Moss Eater (2002-12-06 13:59:00) [10]>DkDimon
Было
type
TSendInfo = packed record
Cmd: String;
Data: Pointer;
end;
Объяснили, что указатели слать бесполезно
Cтало
type
TSendInfo = packed record
Data: String;
end;
Что изменилось?
Вместо двух указателей шлется всего один.
Налицо прогресс :)
Digitman (2002-12-06 13:47:00) [11]
> apple
Это ты к чему ?
apple (2002-12-06 13:21:00) [12]Нет никакой разницы- SendBuf or SendText- строка тот же набор байт- спокойно передаются и тексты и изображения.Просто со строками проще работать.
Digitman (2002-12-05 16:57:00) [13]данные AnsiString-типов следует посылать либо by SendText(), либо двумя последовательными вызовами SendBuf()/SendStream(), первый из которых посылает длину строки, второй - собственно данные строки (находящиеся по адресу PChar(MyString))
Digitman (2002-12-05 16:52:00) [14]
> Вот код.
Та же самая ошибка.
dkDimon (2002-12-05 16:44:00) [15]После долгого перерыва я вернулся опять. Вот код.
Client
type
TSendInfo = packed record
Data: String;
end;
procedure Send;
var
si: TSendInfo;
begin
si.Data := "TestData";
ClientSocket1.Socket.SendBuf(si, SizeOf(si));
{вот тут я не знаю как писать размер - SizeOf(si)?}
end;
Server
procedure Receive;
var
si: TSendInfo;
begin
{а тут я вообще не знаю как получить...}
end;
Вы наверное спросите, не легче ли послать с помощью SendText, т.к. в записи только строка. Нет. Т.к. там будут еще данные - это только пример.
Digitman (2002-11-11 15:57:00) [16]Прекрати мат и свои дурацкие обиды !
И объясняй подробно, что значит
> даже если не пойнтер посылать
Код приводи ! Пусть даже и неработающий ! Только тогда помощь реальную получишь и что-то уяснишь для себя ...
dkDimon (2002-11-11 15:38:00) [17]Удалено модератором
Polevi (2002-11-06 09:14:00) [18]2Моджахед (05.11.02 20:55)
ничего, мастдай все замаршалит :)
Kotka (2002-11-05 22:08:00) [19]А вот мне не нравится эта строка: ServerSocket.Socket.ReceiveBuf(si, ServerSocket.Socket.ReceiveLenth);
хм!
Моджахед (2002-11-05 20:55:00) [20]Ну блин, ну блин, язык так и чешется.
А подумай, как хорошо было-бы... Ты по сетке шлешь селектор и смещение данных. А данные в данный момент в свопе лежат. И умный сокет шлет по шнурку своп-файл. Борландам посоветуем ;)