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

Вниз

работа с сокетами   Найти похожие ветки 

 
Deep   (2002-12-12 01:29) [0]

Вопрос собственно говоря в следующем. Как передавать(принимать)данные при утановленных свойствах ClientType = ctBlocking и
ServerType = stThreadBlocking.

Дело в том, что у меня в программе сервер, в цикле передает клиенту строки, например:

var
Str: string
begin
.....
for i:=0 to 100 do
ServerSocket1.Socket.Connections[0].SendText(Str);
.....
end;

соединение устанавливаю ServerType = stNonBlocking и ctNonBlocking соответственно для клиента, так вот если и клиент и сервер запущены на локальной машине, то все вроде работает нормально, но если на разных то строки теряются, т.е. клиентское приложение получает не 100 строк а скажем 20.

Для проверки пробовал делать в цикле вывод сообщения:

for i:=0 to 100 do
begin
ServerSocket1.Socket.Connections[0].SendText(Str);
ShowMessage(Str);
end;

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

Собственно говоря возвращаясь к началу вопрса, нужен пример программы, работы с сокетами в синхронном режиме.

Заранее благодарен.


 
Nord-Ost   (2002-12-12 06:30) [1]

Элементарно, Ватсон: после передачи строки на сервер жди доклад сервера. А вообще возьми сниффер и посмотри, как общаются клиент с сервером, узнаешь много интересного. (Рекомендую Iris).


 
Deep   (2002-12-12 18:48) [2]

Я делаю проверку

var
Str: string
begin
.....

ServerSocket1.Socket.Connections[0].SendText("SEND_BEG");
for i:=0 to 100 do
ServerSocket1.Socket.Connections[0].SendText(Str);
ServerSocket1.Socket.Connections[0].SendText("SEND_END");

.....
end;

на клиенте в свою очередь проверяю

if Socket.ReceiveText = "SEND_BEG" then
....
if Socket.ReceiveText = "SEND_END" then
....

но как я уже писал в OnRead клиента считываются не все строки, или как я предполагаю я не успеваю их обрабатывать, т.е. я еще не обработал одну строку, как приходит следующая... следовательно предыдущая теряется, так что строку "SEND_END" я вообще могу не получить, как часто и случается :(


 
Nord-Ost   (2002-12-12 19:03) [3]

Я же говорю - после посылки строки жди отчёт о приёме, а потом уже отправляй следущую. В простешем случае принимающая сторона отправляет отправителю пакет, состоящий из одного заголовка. Типа, ОК, сударь, принял во внимание :-) Вот этим и воспользуйся.


 
Nord-Ost   (2002-12-12 19:22) [4]

Вот тебе огрызок статьи, думаю, разберешься без труда:
Send - это неблокирующая операция. Здесь есть небольшие грабли. Если нам необходимо отправить кусок данных ОПРЕДЕЛЕННОГО размера, то send может мгновенно положить в очередь кусок данных (сколько сможет), а остальное из-за неблокирующего режима просто не успеть отправить, перейдя на выполнение следующего кода. Т.к. эта функция возвращает количество отправленных байт, то можно написать функцию доотправки данных. Вот исходники на Delphi:

// DTrSend. первый параметр - буфер для отправки, второй параметр - длинна, третий параметр - сокет.
function DTrsend(Buf : String; LenStr : Cardinal; DTrsock : TSocket) : Cardinal;
var
DopI, DopI1, DopI2, DopI3 : Integer;
begin
Screen.Cursor:=crHourGlass;
Result:=send(DTrsock,Buf,0,0);
// Проверка соединения - отправка 0
if Result=SOCKET_ERROR then begin
Screen.Cursor:=crDefault;
Application.MessageBox(PChar("Error send data. Server was disconnected, closed or not available."),"Error",mb_Ok+mb_TaskModal+mb_IconStop);
closesocket(DTrsock);
Result:=0;
exit;
end;
// обнудение тайм-аута
DopI:=0;
// сколько отправлено
DopI2:=0;
// сколько нужно отправить
DopI3:=LenStr;
// цикл отправки
while true do begin
// отправка данных с нужной позиции нужного кол-ва
DopI1:=send(DTrsock,Buf[DopI2+1],DopI3,0);
// подсчет отправленного
DopI2:=DopI2+DopI1;
// подсчет сколько нужно отправить
DopI3:=DopI3-DopI1;
// если все отправили или тайм-аут - выход
if (DopI2>=LenStr)or(DopI>666) then break;
inc(DopI);
sleep(100);
end;
Result:=DopI2;
if Result<LenStr then begin
Screen.Cursor:=crDefault;
end;
end;



 
Deep   (2002-12-14 03:08) [5]

> Nord-Ost

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


 
Deep   (2002-12-15 20:44) [6]

Так кинет мне кто-нибудь пример? Или никто не знает как работать с сокетами в синхронном режиме.



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

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

Наверх





Память: 0.47 MB
Время: 0.011 c
1-15702
Юный_программер
2003-01-27 14:40
2003.02.06
Как создать подобие планировщика? как запускать в определенное


6-15776
Noname_
2002-12-10 17:07
2003.02.06
502 Proxy Error


14-15880
VID
2003-01-19 22:14
2003.02.06
Как правильно подключать устройства к IDE-шлейфу ?


3-15479
ruslan_as
2003-01-20 14:25
2003.02.06
IB6 подчиненный IBQuery


6-15777
Br@iN
2002-12-08 21:23
2003.02.06
Как скачать файл с сайта?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский