![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
странная проблема с сокетами: [D1, D2, D3, D4, D5, D6, D7, Win95/98, WinME, NT4, Win2k, WinXP]
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;
а вообще бардак у тебя наблюдается в обработчиках и в логике асинхронного коннекта в целом