Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

странная проблема с сокетами: [D1, D2, D3, D4, D5, D6, D7, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2

GroZ ©   (2004-05-20 11:53:00) 

Deiphi 5

Нужно с помощью клиент-сокетов конестится к нескольким серверам (на каждый сервер соответственно по клиент-сокету) т.е. есть массив клиент-сокетов. Пытаюсь сделать это следующим образом:

без переделок:
  for i := 0 to Length(PrmConns)-1 do begin
     if not PrmConns[i].ClientSocket.Active and not PrmConns[i].Connecting then begin
        PrmConns[i].ClientSocket.Close;
        PrmConns[i].Connecting := true;
        PrmConns[i].ClientSocket.Port := PrmConns[i].CurrPort;
        PrmConns[i].ClientSocket.Address := PrmConns[i].IP;
        PrmConns[i].ClientSocket.Open;

     end;
     if PrmConns[i].ClientSocket.Active and PrmConns[i].Connecting then begin
        PrmConns[i].Connecting := False;
     end;
  end;

Если сервер запущен, то всё хорошо работает ... но в противном случае (если сервер не запущен) через несколько часов работы Окна маразмятся ... что-то происходт с сетевым сервисом: перестаёт работать инет, не работает Outlook Express (не может приконнектится к серверу) правда по локалке на Sharing можно зайти ...
Выше приведённый код запускается в Timer-e, каждые 800 мс ..
Также в обработчике ошибки клиент-сокета (ClientSocket.OnError):

PrmConns[i].Connecting := False;
PrmConns[i].ClientSocket.Active := False;
PrmConns[i].CurrPort := PrmConns[i].CurrPort + 1;
if (PrmConns[i].CurrPort < PrmConns[i].Port.s) or (PrmConns[i].CurrPort > PrmConns[i].Port.e) then PrmConns[i].CurrPort := PrmConns[i].Port.s;
ErrorCode := 0;


Создаю клиент-сокет так:
procedure TMyClass.CreateClientSocket(var ClientSocket: TClientSocket);
begin
  ClientSocket := TClientSocket.Create(Application);
  ClientSocket.OnError := ClientSocketError;
  ClientSocket.OnRead := ReadSocket;
  ClientSocket.OnConnect := ClientSocketConnected;
end;



Если у Вас есть какие-нибудь предложения исправления или предположения причины ошибки - буду очень благодарен если поделитесь ими со мной :)


Verg   (2004-05-21 12:41:00) [21]

И все же в, если ты в onError не закроешь сокет (Scoket.Close),  то будет происходить утечка системного ресурса - дескриптора сокета. Т.ч., после нескольких часов такой работы с утечами дескрипторов всекое может случиться....
ClientSocket.Active := false;
Проверяет, что Active был true и только после этого приступает к отсоединению и закрытию дескриптора (closesocket). Но если соединения не произошло, то ClientSocket.Active := false; не сделает ровным счетом ничего, а тем временем сам дескриптор сокета под попытку соединения был уже выделен (ф-ция socket).
Вот и вся!, "хрен", разница...


GroZ   (2004-05-21 12:14:00) [22]


> объясни простыми и понятными словами, какова твоя общаяч задача


Программа - Игра в онлайне, децентрализованная, т.е. нет одного главного сервера .. их несколько ...


> на основании чего ты столь уверен, что 800 мс достаточно
> для осуществления коннекта с любым сервером ?


Совершенно я в этом не уверен и даже не надеюсь ... если внимательно рассмотреть код - то видно что попытка присоедениться не происхоит каждый 800 мс .. каждые 800 мс происхотд проверка текущего состояния и если клиент не присоединён к серверу и программа не ждёт результата от прошлой попытка соединения ( if not PrmConns[i].ClientSocket.Active and not PrmConns[i].Connecting then begin ...) то ТОЛЬКО тогда пытаюсь ещё раз приконнектиться ..


Digitman   (2004-05-21 11:13:00) [23]


> какая на хрен разница сколько элементов в массиве


большая разница ! почему бы мне не предположить, что их там десяток миллионов ? это же - ресурсы , которые ты требуешь от системы ! система же не резиновая !! даже если 2, то не закрывая как положено эти 2 гнезда при неуспешных попытках их коннекта за сотню-другую тиков таймера ты отберешь у системы кучу ресурсов, и система не сможет их выделить иным приложениям (цитирую тебя : "перестаёт работать инет, не работает Outlook Express"), что ты и наблюдаешь !!


> Где какую петрушку ты здесь видиш?


на основании чего ты столь уверен, что 800 мс достаточно для осуществления коннекта с любым сервером ?
объясни простыми и понятными словами, какова твоя общаяч задача


GroZ   (2004-05-21 10:47:00) [24]

Удалено модератором
Примечание: Следи за речью...


Digitman   (2004-05-21 10:42:00) [25]

я задал вопросы


GroZ   (2004-05-21 10:27:00) [26]

Socket.Close; не помогает ... те же симптомы ...

Так в чём бардак?


Digitman   (2004-05-20 13:33:00) [27]


> ClientSocket.Active := False; не тоже что и Socket.Close;?


нет, далеко не то же


> Выше приведённый код запускается в Timer-e, каждые 800 мс


и сколько элементов в массиве PrmConns ?
мне непонятно, каков прикладной смысл всей этой петрушки


GroZ   (2004-05-20 13:12:00) [28]

а ClientSocket.Active := False; не тоже что и Socket.Close;?

в чём бардак, поясните?


Digitman   (2004-05-20 12:30:00) [29]

последней строкой в обработчик OnError добавь

Socket.Close;

а вообще бардак у тебя наблюдается в обработчиках и в логике асинхронного коннекта в целом


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо