Текущий архив: 2006.07.30;
Скачать: CL | DM;
Вниз
ClienSocket и ServerSocket Найти похожие ветки
← →
serko © (2006-01-27 00:03) [0]Вот у меня одна прога типа сервер а другая клиент!
Естественно что Клиент подключается к уже запущенному Серверу.
Но вот если запустить клиента когда сервер еще не запущен то выскакивает ошибка "Asynchronous socket error 10061".
Как сделать так чтобы Клиент подключался до тех пор пока не запустится Сервер, без вывода этой ошибки?
← →
Digitman © (2006-01-27 09:13) [1]в событии OnError:
Errorcode := 0;
Socket.Close;
ClientSocket.Open;
← →
serko © (2006-01-27 23:31) [2]Оооооооооо Спасибо тебе большое!
← →
serko © (2006-01-31 00:55) [3]Че то оно, работает но не всегда, точнее неработает не всегда! Вообщем только иногда работает!
Все я сделал как посоветовал:
> Digitman © (27.01.06 09:13) [1]
Но подключение почему то не происходит! у меня все делается по сети т.е. Серверная программа на одном компе а Клиентская на другом!
Может чето еще посоветуете?
← →
serko © (2006-01-31 01:22) [4]Вот что только что заметил!
Если Клиентская программа запущена и потом запустить Серверную, то все ок, а если сразу же закрыть Серверную и снова открыть то уже не пашет!
Че надо изменить или добавить?
← →
Digitman © (2006-01-31 08:25) [5]
> если сразу же закрыть Серверную и снова открыть то уже не
> пашет
А что должно "пахать"-то ?
Коннект ведь успешно состоялся .. т.е. ответ на свой первоначальный вопрос ты получил ..
← →
serko © (2006-01-31 15:35) [6]
> А что должно "пахать"-то ?
Ну при втором запуске серверной программы не происходит соединение с клиентом.
← →
Digitman © (2006-01-31 16:22) [7]
> при втором запуске серверной программы не происходит соединение
> с клиентом.
И с какого перепугу сервер при запуске должен вдруг соединяться с каким-то там сраным клиентом ?
← →
kami © (2006-01-31 21:42) [8]Digitman © (31.01.06 16:22) [7]
:)))
serko © (31.01.06 15:35) [6]
При отключении клиента срабатывает OnDisconnect, а не OnError. Дальше - включаем логическое мышление и сопостовляем с Digitman © (27.01.06 9:13) [1]
← →
serko © (2006-02-01 00:35) [9]
> Digitman © (31.01.06 16:22) [7]
а я бы на твоем месте не предирался к каждому слову, а помог бы!
> При отключении клиента срабатывает OnDisconnect, а не OnError.
Это я и без тебя знаю!
← →
kami © (2006-02-01 01:33) [10]serko © (01.02.06 0:35) [9]
Если такой знающий, то почему строем не ходишь?
← →
Digitman © (2006-02-01 10:09) [11]
> не предирался к каждому слову, а помог бы
Ну как тебе помочь, если ты вразумительно задачу/проблему описать не можешь ?
После успешного установления соединения, если сервер разрывает его по своей инициативе, у клиента возникает событие OnDisconnect, в обработчике которого, например, следует асинхронно послать форме (на которой лежит ClientSocket) условное сообщение, при получении и обработке которого выполняется ClientSocket.Open
← →
serko © (2006-02-03 17:39) [12]Вообще я сделал вроде - ошибка больше не выскакивает! Спасибо всем!
← →
serko © (2006-02-13 22:54) [13]Странно, но она всеравно выскакивает!
Расскажу подробно че я сделал:
В FormCreate: ClientSocket1.Open;
В таймере: If not ClientSocket1.Active then
ClientSocket1.Open;
Ну и в ClientSocket1Error: Errorcode := 0;
Socket.Close;
ClientSocket1.Close;
Все вроде бы сначала ок, но иногда (при переодическом запуска\закрытии серверной программы), появляются такие глюки: на сервере сразу при запуске "Stack overlow", а на клиентской при обработке события в таймере ошибка "Asynchronous socket error 10059" API "connect".
Что еще можна сделать?
← →
Digitman © (2006-02-14 08:29) [14]
> Что еще можна сделать?
Исправить ошибки в коде сервера.
← →
serko © (2006-02-14 11:23) [15]Какие ошибки?
на сервере все происходит так:
OnAccept и OnClientDisconnect -
ListView1.Items.Clear;
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText("#N");
OnClientError - ErrorCode:=0;
OnClientRead - обрабатываются сообщения от Клиента!
← →
Digitman © (2006-02-14 11:39) [16]см. http://citrix.pp.ru/faqs/tcp_errors.html
10059 WSAETOOMANYREFS Too many references (Слишком много ссылок).
На какой-то объект ядра создано слишком много ссылок, превышающих системные ресурсы.
> Какие ошибки?
В момент OnClientDisconnect отключившийся клиент все еще присутствует в списке ActiveConnections, хотя "связь" с ним уже невозможна (любые попытки передачи/приема инф-ции, относящейся к этому клиенту, приведут к исключению)
← →
serko © (2006-02-14 13:08) [17]Хорошо уговорил, происходит такое!
Как же его тогда удалить из списка Включенных?
использование Try и Except тоже не помогает!
← →
Digitman © (2006-02-14 13:13) [18]
> Как же его тогда удалить из списка Включенных?
А никак его не надо удалять ..
Он сам "удалится" сразу же после возврата из обработчика OnClientDisconnect
> использование Try и Except тоже не помогает
Не выдумывай, замечательно "помогает"
← →
serko © (2006-02-14 13:44) [19]
> Не выдумывай, замечательно "помогает"
Ну покажи пример в котором помогает! У меня всеравно выскакивают ошибки!
← →
Digitman © (2006-02-14 14:09) [20]procedure TSomeForm.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
with ServerSocket1.Socket do
for i := 0 to ActiveConnections-1 do
if Connections[i] <> Socket
try
Connections[i].SendText("#N");
except
end;
end;
← →
serko © (2006-02-14 14:51) [21]Почему тогда не помогает в этом случае?
Try
ClientSocket1.Open;
Except
End;
← →
Digitman © (2006-02-14 14:56) [22]
> Почему тогда не помогает в этом случае?
Потому что это совершенно другой случай.
Ставь ClientType = ctBlocking - поможет и в этом случае.
← →
serko © (2006-02-14 15:17) [23]Да действительно помогло, но это получается что с сокетом нужно работать как с потоком, а у меня уже много сделано для ctNonBlocking
← →
Digitman © (2006-02-14 15:23) [24]
> это получается что с сокетом нужно работать как с потоком
Чего-чего ?!
> у меня уже много сделано для ctNonBlocking
И, видимо, неправильно сделано, потому и глюк на глюке.
Методы открытия/передачи/приема в режиме ctNonBlocking работают асинхронно, а для извещения об асинхронных ошибках как раз и придуманы события On[Client]Error.
← →
serko © (2006-02-14 15:32) [25]
> Чего-чего ?!
Ну вот я в одной из статеек нашел:
ClientType - тип соединения. ctNonBlocking - асинхронная передача данных, т.е. посылать и принимать данные по сокету можно с помощью OnRead и OnWrite. ctBlocking - синхронная (одновременная) передача данных. События OnRead и OnWrite не работают. Этот тип соединения полезен для организации обмена данными с помощью потоков (т.е. работа с сокетом как с файлом);
← →
Digitman © (2006-02-14 15:37) [26]
> serko © (14.02.06 15:32) [25]
> Этот тип соединения полезен для организации обмена данными
> с помощью потоков
Заметь - именно полезен !
Но вовсе не обязателен.
← →
Digitman © (2006-02-14 15:49) [27]Точнее так - для приема/передачи данных с использованием класса TWinSocketStream этот режим действительно обязателен.
Но ничто не мешает обходиться без TWinSocketStream и безо всяких "потоков". Здесь важно другое - методы коннекта/приема/передачи в режиме ctBlocking являются синхронными, из вызовы блокируют выполнение последующих операторов до момента успешного выполнения либо возникновения искл.ситуации
← →
serko © (2006-02-14 15:58) [28]Хорошо! А ты можеш привести причерчик работы для режима ctBlocking?
← →
Digitman © (2006-02-14 16:05) [29]try
CS.Open;
except
.. не удалось соединиться по тем или иным причинам ..
end;
...
try
CS.SendText("Текст");
except
.. не удалось передать данные по тем или иным причинам ..
end;
...
try
RcvdText := CS.ReceiveText;
except
.. не удалось принять данные по тем или иным причинам ..
end;
← →
serko © (2006-02-14 16:37) [30]Ну всеравно появляются вопросы:
1. В каких событиях обрабатывать эти примеры для СЕРВЕРА и КЛИЕНТА, ведь в таком случае OnRead и OnClientRead не срабатывают?
2. Как узнать что удаленная машина отправила текст, чтобы я смог вызвать ПРИЕМ?
← →
Digitman © (2006-02-14 16:42) [31]
> 1. В каких событиях обрабатывать эти примеры для СЕРВЕРА
> и КЛИЕНТА, ведь в таком случае OnRead и OnClientRead не
> срабатывают?
А что , разве на событиях свет клином сошелся ? Без событий уже никак ?
> 2. Как узнать что удаленная машина отправила текст, чтобы
> я смог вызвать ПРИЕМ?
Если TCustomWinSocket.ReceiveLength() вернула результат больше 0, это говорит о непустом буфере приема
← →
serko © (2006-02-14 16:52) [32]Ну ладно хватит на сегодня тебя мучать, ты мне и так много чего разъяснил и за это тебе большое спасибо! Ну если что, то я вернусь!
← →
Digitman © (2006-02-14 17:31) [33]
> Ну ладно хватит на сегодня тебя мучать
Приходите еще).. Желательно - со своими тапками
← →
serko © (2006-02-16 16:54) [34]И вот я снова тут, в своих тапках! :)
Мне все же хочется сделать по-моему т.е. с ctNonBlocking.
У меня клиентские программы стоят на слабеньких компах с WIN 98, по сравнению с сервером WIN XP - Celeron 2000 Mhz.
Наверное поэтому на клиентах через некоторое время и выскакивает ошибка типа:
"10055 WSAENOBUFS No buffer space available (Закончились буферы).
Невозможно осуществить операцию с сокетом, поскольку системе не хватает буферного пространства или переполнена очередь. Это означает, что WinSock временно не хватает буфров. Это не должно вызывать проблем, если не продолжается долгое время."
Как я уже говорил у меня в таймере происходит:
If not ClientSocket1.Active then
ClientSocket1.Open;
Try
Begin
ClientSocket1.Socket.SendText("Text");
End;
Except
End;
Может как-то можна очищать этот буфер? На более мощных компах, за такой же промежуток времени ошибка не выскакивает!
Задача все таже! Клиент должен пытаться подключиться к серверу, до успешного соеденения. Вслучае разрыва связи все должно повторяться! И что самое главное БЕЗ выскакивающих ОШИБОК!
← →
Digitmn (2006-02-17 12:30) [35]
> Клиент должен пытаться подключиться к серверу, до успешного
> соеденения
Фактом успешного соединения является факт возникновения события OnConnect
← →
serko © (2006-02-18 21:09) [36]Вот сегодня оставил клиентскую прогу на более менее нормальном компе, так при выключеной серверной программе, сутки простояла и все ок! А на слабых компах глючит!
Что посоветуете? Можно ли как то буфер чистить?
← →
serko © (2006-02-21 22:32) [37]Что нет вариантов?
А у меня еще вопросы появились:
1. Что означает ошибка Stack Overflow? Я так подозреваю она происходит при выполнении кода:
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText("#N");
Суть его такова, что отсылается запрос на NiCkName КЛИЕНТА ввиде "#N", и потом уже каждый клиент присылает СЕРВЕРУ свой NickName. На нормальных компах эта ошибка не выскакивает, но почемуто приходит 2 ответа на запрос в виде "#NUser_1#NUser_1". Помогите разобраться!
2. И еще на КЛИЕНТ у меня стоит на 10 компах с 98 виндой, так вот на 9 прога запускается нормально, а на 10-ом при попытке открыть Сокет пишет "Can"t create new socket". Что это может быть? Может в винде надо чето настроить?
Ребя помогите в этом разобраться!
← →
atruhin © (2006-02-22 06:42) [38]1. у тебя ошибки в программе.
2. в windows есть ограничение на кол-во одновременных подключений, не более 10, этого ограничения нет у серверных систем.
← →
Сергей М. © (2006-02-22 11:09) [39]
> Что означает ошибка Stack Overflow?
Переполнение стека.
Где-то ты допустил бесконечную рекурсию.
← →
serko © (2006-02-22 14:18) [40]1. Что такое рекурсия? Это связано с СОКЕТАМИ?
Эта ошибка на Pentium 133 выскакивает сразу при запуске проги, а на Athlon 2000+ ее нет вообще!
2. Но ведь не более 10, а 10 же еще можна?
3. И еще вопрос не в тему: Как в ListView программно выделить все имеющиеся Item?
← →
Сергей М. © (2006-02-26 11:52) [41]
> Что такое рекурсия?
Вызов подпрограммой самой себя.
пример бесконечной рекурсии и гарантированного получения при этом SO-исключения:
procedure DummyRecursiveProc;
begin
DummyRecursiveProc;
end;
← →
serko © (2006-02-28 23:39) [42]Вот что я заметил: если при Connect или Disconect посылать запрос на имя всех активных пользователей таким образом:
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText("#N");
то выскакивает выше указанная ошибка, но при этом значение ServerSocket1.Socket.ActiveConnections почему то в два раза больше (по крайней мере при запуске программы, если же сразу повторить запрос то все становится нормуль) чем пользователей от которых пришел ответ т.е. его ИМЯ, а вот в примере приведенном Digitman © (14.02.06 14:09) [20], при запуске проги я не от всех получаю их имя, но при повторном запросе все становится номуль, но при этом ошибка Stack overflow вроде не выскакивает!
Ошибки у Клиента все еще выскакивают, при длительном отсутствии соединения!
Что еще подскажите, посоветуете?
← →
Сергей М. © (2006-03-01 09:00) [43]Приводи полный код клиента и сервера.
По тем обрывкам что ты привел никаких умозаключений и рекомендаций сделать невозможно.
← →
serko © (2006-03-02 16:46) [44]Ну вот вам код СЕРВЕРА:
procedure TForm1.FormCreate(Sender: TObject);
begin
ListView1.Items.Clear;
{Устанавливаем порт}
ServerSocket1.Port := 1001;
{Запускаем сервер}
ServerSocket1.Open;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var s, to_: string;
i: Integer;
Tsr:tSearchrec;
l: Integer;
buf: PChar;
src: TFileStream;
begin
{сохраняем в s присланную нам строку}
s := Socket.ReceiveText;
//Если кто-то прислал нам свое имя
if Copy(s,1,2) = "#N" then
begin
Delete(s,1,2);
//Поиск компьютеров.
with ListView1.Items.Add do
Begin
Caption:=s;
SubItems.Add("");
SubItems.Add("");
SubItems.Add("");
SubItems.Add("");
SubItems.Add("");
SubItems.Add("");
for i:=0 to ListView1.Items.Count-1 do
begin
....
end;
end;
Exit;
end;
//Если прислали запрос на СПИСОК курсантов
if Copy(s,1,5) = "#Spis" then
begin
s:="#Spis";
for i:=0 to ListView1.Items.Count-1 do
S:=s+ListView1.Items.Item[i].SubItems.Strings[1]+":"+
ListView1.Items.Item[i].SubItems.Strings[2]+";";
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
end;
procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var i: Integer;
begin
{Кто-то присоединился или отсоединился? Нет проблем!
Запрашиваем у всех юзеров их имена}
ListView1.Items.Clear;
with ServerSocket1.Socket do
for i := 0 to ActiveConnections-1 do
if Connections[i] <> Socket then
try
Connections[i].SendText("#N");
except
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ServerSocket1.Close;
end;
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode:=0;
end;
А вот и КЛИЕНТ:
procedure TMainForms.FormCreate(Sender: TObject);
Var t:textfile;
ScaleWidth, ScaleHeight, ScreenScale : Real;
begin
Sms:=false;
{Если соединение уже установлено, то обрываем его}
if ClientSocket1.Active then
ClientSocket1.Close;
{Устанавливаем свойства Host и Port}
IP:=MainForms.ReadINI("c:\windows\Systems.ini","Server","IP");
ClientSocket1.Host := ip;
Val(MainForms.ReadINI("c:\windows\Systems.ini","Server","Port"),Port,code);
ClientSocket1.Port := Port;
{Пытаемся соединиться}
if IP<>"" then ClientSocket1.Open;
KeyPreview := true;
end;
procedure TMainForms.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var s,to_: string;
begin
{присваиваем s полученную от сервера строку}
s := Socket.ReceiveText;
{Если нам прислали запрос на наше имя юзера}
if Copy(s,1,2) = "#N" then
begin
{Посылаем ответ}
Pc:=MainForms.ReadINI("c:\windows\Systems.ini","Dir","Pc");
Try
ClientSocket1.Socket.SendText("#N"+pc);
Except
End;
Exit;
end;
{Если нам прислали СПИСОК юзеров}
if Copy(s,1,5) = "#Spis" then
begin
Delete(s,1,5);
i:=1;
while Spis[i,1]<>"" do
Begin
Spis[i,1]:="";
Spis[i,2]:="";
i:=i+1;
End;
i:=1;
While Length(s)<>0 do
Begin
Spis[i,1]:=Copy(s,1,pos(":",s)-1);
Delete(s,1,pos(":",s));
Spis[i,2]:=Copy(s,1,pos(";",s)-1);
Delete(s,1,pos(";",s));
i:=i+1;
End;
Spis_Flag:=true;
Exit;
end;
{Если нам прислали приватное сообщение (или не нам :) )}
if Copy(s,1,2) = "#P" then
begin
Delete(s,1,2);
{Выделяем в to_ - кому оно предназначено}
to_ := Copy(s,1,Pos(";",s)-1);
Delete(s,1,Pos(";",s));
if (to_ = pc) then
begin
//-----------------------------------------------------------------------------
MainForms.Memo1.Lines.Insert(0,s);
//Пришел курсант
//Выделяем фамилию и группу курсанта
If Copy(s,1,4) = "#F_G" then
begin
Delete(s,1,4);
MainForms.WriteINI(Put+"Options.ini","User","Fam",Copy(s,1,Pos(";",s)-1));
Delete(s,1,Pos(";",s));
MainForms.WriteINI(Put+"Options.ini","User","Group",Copy(s,1,Pos(";",s)-1));
Delete(s,1,Pos(";",s));
MainForms.WriteINI(Put+"Options.ini","User","Rezhim",Copy(s,1,Pos(";",s)-1));
Delete(s,1,Pos(";",s));
MainForms.WriteINI(Put+"Options.ini","User","Timer",Copy(s,1,Pos(";",s)-1));
Delete(s,1,Pos(";",s));
Connekt.Color:=clSkyBlue;
Fam:=MainForms.ReadINI(put+"Options.ini","User","Fam");
Gr:=Strtoint(MainForms.ReadINI(put+"Options.ini","User","Group"));
Rezhim:=MainForms.ReadINI(put+"Options.ini","User","Rezhim");
Connekt.Label2.Caption:=Fam+#13+"из Группы №"+inttostr(gr);
Connekt.button1.Visible:=true;
Connekt.ActiveControl:=Connekt.button1;
End;
end;
Exit;
end;
end;
procedure TMainForms.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
Errorcode := 0;
Socket.Close;
ClientSocket1.Close;
end;
procedure TMainForms.Timer2Timer(Sender: TObject);
begin
If not ClientSocket1.Active then
Begin
ClientSocket1.Open;
End else
Begin
ClientSocket1.Socket.SendText("#P#Bil"+Pc+";"+MainForms.ReadINI(Put+"Options.ini","Bilet","Nom")+";"+
MainForms.ReadINI(Put+"Options.ini","Bilet","Oshib")+";");
End;
end;
Покажите и подправте места где может зарождаться ошибка!
← →
Сергей М. © (2006-03-02 16:48) [45]и ТЗ (полное !!) еще изложи.
← →
serko © (2006-03-02 17:09) [46]
> и ТЗ (полное !!) еще изложи.
Что за "ТЗ"?
← →
Сергей М. © (2006-03-03 08:14) [47]Техническое задание
← →
serko © (2006-03-03 14:04) [48]Ааааа ну так бы и раньше сказал!
Задача такая: Основное это управлять КЛИЕНТским компом и приложением. Хотелось бы что это происходило так: КЛИЕНТская прога запускаеся и ждет подключения сервера; если сервер отключился то она снова переходит в режим "Попытки подключения" (не хочется чтобы всегда была запущена СЕРВЕРная прога), у меня при отключенном сервере через некоторое время у клиента выскакивает ошибка! А при запуске серверной программы в LISTVIEW должен появляться список подключенны клиентов, ну и обновляться при подключении\отключении КЛИЕНТа. Вот здесь у меня возникают проблемки, в остальном думаю разберусь!
← →
Сергей М. © (2006-03-03 14:11) [49]Это все в локальной сети должно работать ?
← →
serko © (2006-03-03 23:37) [50]
> Это все в локальной сети должно работать ?
Так точно!
← →
Сергей М. © (2006-03-06 13:05) [51]Начнем по порядку ..
> procedure TForm1.ServerSocket1Accept(Sender: TObject;
> Socket: TCustomWinSocket);
> var i: Integer;
> begin
> {Кто-то присоединился или отсоединился?
Причем здесь "отсоединился" ?
Accept-событие фиксирует факт подтверждения сервером клиентского запроса на соединение
← →
serko © (2006-03-06 21:13) [52]Ну у меня OnAccept и OnDisconnect использует одну процедуру ServerSocket1Accept т.к. коды там одинаковы!
← →
Сергей М. © (2006-03-07 08:45) [53]А зачем всякий раз при акцепте или дисконнекте некоего очередного клиента запрашивать у остальных активных клиентов их имена ? Они что, измениться разве могут ?
И зачем чистить ListView при этом ?
← →
serko © (2006-03-07 23:41) [54]
> Сергей М. © (07.03.06 08:45) [53]
Тут я с тобой полностью согласен, я просто сделал как было в статье. Думаеш это разрешит мою проблему?
Тогда в сообщении нужно осылать ИМЯ подключенного или отключенного клиента и потом его добавлять или искать и удалять из ListView?
P.S.Но ведь когда я отсылал те или иные сообщения для ВСЕХ клиентов, тоже глюки были!
← →
serko © (2006-03-10 22:27) [55]Сделал! При запуске ошибка вроде не выскакивает!
Но у КЛИЕНТА ошибки все таки выскакиваю при долгом дисконекте!
← →
serko © (2006-03-15 01:29) [56]Вопрос: "У КЛИЕНТА выскакиваю ошибки при долгом дисконекте!" остается в силе!
И еще: "Почему ServerSocket1.SocketActiveConnections иногда бывает больше реального числа самих ClientSocket? Как лишние принудительно отключить?"
← →
Сергей М. © (2006-03-15 09:24) [57]
> serko © (15.03.06 01:29) [56]
> выскакиваю ошибки при долгом дисконекте
Что такое "долгий дисконнект" ? Какие конкретно ошибки ?
> Почему ServerSocket1.SocketActiveConnections иногда бывает
> больше реального числа самих ClientSocket?
Не бывает такого.
← →
serko © (2006-03-15 12:52) [58]
> Не бывает такого.
Ну если бы не было такого я бы не говорил. Я взял и проверил - кинул Label а на него ServerSocket1.SocketActiveConnections. И почти всегда показывает больше чем есть, только иногда реальное число!
> Что такое "долгий дисконнект" ? Какие конкретно ошибки ?
Читай внимательнее ранние посты.
Ну если я закрыл СЕРВЕР, то клиент находится в Disconnect. Так вот если он в Diconnect находится 1 мин, то все ок а если допустим минут 15, то выскакивают такие ошибки:
"10055 WSAENOBUFS No buffer space available (Закончились буферы).
Невозможно осуществить операцию с сокетом, поскольку системе не хватает буферного пространства или переполнена очередь. Это означает, что WinSock временно не хватает буфров."
Как их избежать?
← →
Сергей М. © (2006-03-15 12:57) [59]
> serko © (15.03.06 12:52) [58]
> кинул Label а на него ServerSocket1.SocketActiveConnections
В обработчике КАКОГО события сервера ты это делаешь ?
Это же крайне важно ...
> 10055 WSAENOBUFS
Значит ты неверно обрабатываешь OnError
← →
serko © (2006-03-15 16:50) [60]
> В обработчике КАКОГО события сервера ты это делаешь ?
> Это же крайне важно ...
Та я токо не делал! и в Onread просто по нажатию кнопки, точного числа не добивался!
> Значит ты неверно обрабатываешь OnError
Ну а как надо обрабатывать шоб ошибка не вылазила?
Дело в том шо у меня дома скоко бы не стояла ошибка не вылазит, а на др. компе Win 98 и видимо буфер маленький вот и вылазит такая ошибка!
← →
Slavjanin (2006-03-15 21:10) [61]Здраствуйте, предложите пожалуйста мне исходник сканера портов, или дайте ссылку. Спасибо
← →
Сергей М. © (2006-03-16 08:58) [62]
> serko © (15.03.06 16:50) [60]
> точного числа не добивался
Ну какая-то закономерность хоть наблюдается ?
> буфер маленький
Суть ошибки (10055 WSAENOBUFS) заключается в слишком большом кол-ве созданных тобой гнезд в клиентском приложении.
Создание нового гнезда происходит всякий раз при выполнении метода TClientSocket.Open, а уничтожение - при выполнении TCustomWinSocket.Close или TCustomWinSocket.Disconnect(хендл гнезда).
Успешный вызов метода TClientSocket.Open (т.е. вызов не приведший к исключению) в неблок.режиме нельзя интерпретировать как факт успешного установления соединения - об этом тебя известит асинхронное событие OnConnect. Начинать прием/передачу следует не ранее чем возникнет это событие.
После вызова TClientSocket.Open вместо события OnConnect может возникнуть событие OnError, говорящее о невозможности установки соединения с сервером по тем или иным причинам. Детальная инф-ция об этой причине передается параметром ErrorCode в обработчик события OnError. Кроме того, событие OnError может возникнуть и позже, уже после события OnConnect, в этом случае оно говорит об ошибках в ходе приема/передачи, например, о неожиданном разрыве соединения со стороны сервера в момент когда была инициирована асинхронная операция чтения/записи.
В любом случае в OnError можно (а в случае ошибки, связанной с невозможностью установления коннекта - обязательно) выполнить метод Socket.Close (Socket в дан.случае - это параметр, переданный в обработчик OnError, а не ClientSocket !), что приведет к безусловному уничтожению созданного ранее при вызове ClientSocket.Open гнезда, если оно еще не уничтожено на этот момент. После этого , если необходимо, можно проанализировать ErrorCode на предмет дальнейших действий и сбросить его в 0, чтобы не "выскочило" окно асинхронного сообщения об ошибке.
Далее по ходу выполнения обработчика OnError, если необходимо повторить попытку коннекта, можно активизировать таймер, в обработчике которого собственно выполнить ClientSocket.Open и тут же деактивировать таймер.
← →
serko © (2006-03-16 23:53) [63]Отето ответ и я понимаю! все бы так отвечали!
Спасибо, тебе, попробую сделать правильный вывод!
← →
serko © (2006-03-17 23:01) [64]Всеравно ниче не получается!
в таймере пишу:
ClientSocket1.Open;
Timer1.Enabled:=false;
а в OnError:
Errorcode:=0;
Socket.Close;
Timer1.enabled:=true;
и Вот что получается: Когда запустился КЛИЕНТ, произошло соединение и таймер выключился. Но когда я закрываю СЕРВЕР и снова его запускаю то уже connect не происходит (таймер то остановлен, и OnError выполняется).
Как симитировать ошибку? Или мож еще что подскажеш?
← →
Сергей М. © (2006-03-20 09:08) [65]
> serko © (17.03.06 23:01) [64]
> я закрываю СЕРВЕР
Если это сделано штатно (ServerSocket.Close), то у клиента возникнет событие OnDisconnect, в обработчике которого можно запустить таймер.
← →
serko © (2006-03-20 13:42) [66]Попробуем еще так! Спасибо!
← →
serko © (2006-03-21 22:20) [67]Ты знаеш все пока работает - ПОЛЕТ нормальный!
ЕЩе раз спасибо!
← →
Fandros © (2006-03-22 19:37) [68]
> Задача такая: Основное это управлять КЛИЕНТским компом и
> приложением. Хотелось бы что это происходило так: КЛИЕНТская
> прога запускаеся и ждет подключения сервера; если сервер
> отключился то она снова переходит в режим "Попытки подключения"
> (не хочется чтобы всегда была запущена СЕРВЕРная прога),
> у меня при отключенном сервере через некоторое время у
> клиента выскакивает ошибка! А при запуске серверной программы
> в LISTVIEW должен появляться список подключенны клиентов,
> ну и обновляться при подключении\отключении КЛИЕНТа. Вот
> здесь у меня возникают проблемки, в остальном думаю разберусь!
>
У меня примерно такая-же задача, но клиент должен находиться в сильно подправленной компоненте или в специальном классе! Поэтому использование таймера на форме - не подходит! Как можно заставить переконектиться клиенту (при мягком отрубе сервера)???
обработчик OnDisconnect не игнорирует команду ClientSocket.Open;
← →
Сергей М. © (2006-03-23 08:10) [69]
> Fandros © (22.03.06 19:37) [68]
> использование таймера на форме - не подходит
Ничто не мешает создать таймер "не на форме".
Да и форма собственно ни при чем - твой "сильно подправленный компонент или специальный класс" тоже может не иметь к форме никакого отношения.
Страницы: 1 2 вся ветка
Текущий архив: 2006.07.30;
Скачать: CL | DM;
Память: 0.7 MB
Время: 0.034 c