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

Вниз

TServerSocket, как узнать IP клиента при подключении.   Найти похожие ветки 

 
ZV ©   (2010-09-13 23:20) [40]

Спасибо всем за советы.  Я все таки сделал определение всего IP а не последней цифры , преобразовать в цифровой  формат  Socket.RemoteAddress; у меня не получилось  по этому создал массив IP адресов в текстовом формате и сравниваю. В принципе работает меня пока устраивает , но возникла  новая проблема. В обработчике ServerSocket1ClientConnect   я определи IP клиента , выяснил, что клиенту доступ закрыт, теперь мне нужно его отключить через ServerSocket.Socket.Connections[?].Close . А   как я его отключу? Я знаю только его  IP но не номер его подключения. Как узнать какой номер подключения ?


 
ZV ©   (2010-09-14 12:20) [41]

Пока мне не ответили на вопрос я сделал так. При коннекте клиента  в поле клиента о номере подключения записываю  
NomberConnection:=ServerSocket1.Socket.ActiveConnections
И вроде  получаю номер подключения. Как то просто получилось. Может я что то упустил из виду?


 
Сергей М. ©   (2010-09-14 13:48) [42]


> ZV ©   (14.09.10 12:20) [41]


Накой шиш тебе этот "номер" ?

У тебя возникло событие OnClientConnect, фактическим параметром его обработчика тебе передан объект Socket, у него есть св-во RemoteAddress (и RemoteAddr - не суть как важно). Т.е. в момент обработки события ты знаешь адрес удаленного клиента. Ну так и отключай его, если нужно, впрямо в этом же обработчике вызовом Socket.Close ! За каким тебе понадобилось лезть в список активных соединений-то ?)


 
Anatoly Podgoretsky ©   (2010-09-14 13:56) [43]


> За каким тебе понадобилось лезть в список активных соединений-
> то ?)

Он нехочет слушать этот совет


 
ZV ©   (2010-09-14 13:57) [44]

У активных пользователей есть определенное  время нахождения на сервере. После тог как время истекло мне нужно этого пользователя от сервера отключить. И тут возникает вопрос - как? . Я знаю только IP  а не номер его подключения. А отключить я могу конкретного клиента только через ServerSocket.Socket.Connections[f].Close

Где f и есть номер подключения.
Поэтому я и хочу при коннекте клиента к серверу узнать номер его подключения и занести его  в запись о данных клиента клиенте. И когда его время истекает я обращаюсь к записи нахожу его номер подключения и отключаю


 
ZV ©   (2010-09-14 14:03) [45]


> NomberConnection:=ServerSocket1.Socket.ActiveConnections


Скорей всего это фигня. Это может работать только если клиенты будут отключаться в такой же последовательности как и подключались.
Мда, хрень


 
Сергей М. ©   (2010-09-14 14:09) [46]


> нужно этого пользователя от сервера отключить. И тут возникает
> вопрос - как? . Я знаю только IP


Не только. Еще и порт знаешь.
Вот эта комбинация IP-адреса и порта как раз и есть уникальный идентификатор клиента в списке активных клиентов сервера.
Остается в цикле пробежаться по всем активным соединениям в списке ActiveConnections, сравнить каждое соединение на совпадение удал. адреса и порта с искоммой комбинацией. Нафих нужен номер акт.клиента в этом списке, если он может измениться в любой момент времени ?

Ты пораскинь мозгами-то - вот, к примеру, последовательно подключились три клиента А, В и С. В списке ActiveConnections они фигурируют под индексами 0,1 и 2 соответственно. Теперь клиент В отключился. Вопрос на засыпку: каков теперь индекс соединения клиента С в этом списке ?


 
Сергей М. ©   (2010-09-14 14:11) [47]

Ты-то запомнил клиента С в момент его подключения под индексом 2, а после отключения клиента В клиент С вовсе не третий (по порядку) в этом списке

)


 
Palladin ©   (2010-09-14 14:34) [48]

"... да и цикл удаления из списка у него с единицы начинался" (С)


 
ZV ©   (2010-09-14 14:56) [49]


> Сергей М


> если он может измениться в любой момент времени ?

Я вник в суть проблемы

Значит я должен сделать приблизительно так ?


for i:=0 to ServerSocket1.Socket.ActiveConnections do
a:=ServerSocket1.Socket.Connections[i].RemoteAddress ;
for d:=1 to MaxClient do
if a=Client[d].IP then
begine
if Client[d].Status=false then
begin
ServerSocket1.Socket.Connections[i].Close ;
end
end


 
Сергей М. ©   (2010-09-14 15:07) [50]

Ну а где в этом "приближительно" сравнение порта ?


 
ZV ©   (2010-09-14 15:13) [51]

А порт на кой нужен? IP не достаточно?


 
Сергей М. ©   (2010-09-14 15:18) [52]


> А порт на кой нужен?


А что мешает двум совершенно разным клиентам подключиться к твоему серверу под одним и тем же IP-адресом ?
Ничто)


 
ZV ©   (2010-09-14 15:30) [53]


> Сергей М

Понял.

Сейчас вроде как все понятно. Но есть одна кака с которой я не знаю как бороться . У клиента есть такая особенность как неожиданный разрыв соединения без всяких уведомлений и потом повторное подключение, естественно у меня на сервер возникает ошибка и сервер падает. И эта кака не куда не денется,  по этому с ней нужно как то бороться. Я так понимаю что нужно сделать процедуру обработчик ошибки сокета
procedure TForm1.KaKa(Sender: TObject; Error: Exception);
begin
 If (Error.ClassName = "ESocketError") then
   Begin
    // Что написать при обрыве связи с клиентом и повторном его подключении  я не пойму
   end
 else Application.ShowException(Error);  
end;


 
Anatoly Podgoretsky ©   (2010-09-14 15:37) [54]

> ZV  (14.09.2010 15:13:51)  [51]

ИП недостаточно, подключений может быть много.


 
Anatoly Podgoretsky ©   (2010-09-14 15:38) [55]


> А что мешает двум совершенно разным клиентам подключиться
> к твоему серверу под одним и тем же IP-адресом ?

Особенно из-за НАТ


 
Сергей М. ©   (2010-09-14 15:38) [56]

А где у тебя обработчик OnClientError ?


 
Anatoly Podgoretsky ©   (2010-09-14 15:40) [57]

Прощай Сеть


 
ZV ©   (2010-09-14 15:51) [58]


> А где у тебя обработчик OnClientError ?

Нет, его у меня.
А в каком случае он сработает? И что в нем делать?

> Прощай Сеть

:)


 
Сергей М. ©   (2010-09-14 16:09) [59]

OnClientError может сработать в случае возникновения отказа в ходе выполнения сервером того или иного метода приема или передачи. Параметр ErrorCode укажет причину отказа. Самое простое и надежное - тут же закрыть соединение вызовом Socket.Close.

Если при вызове сервером того или иного метода приема или передачи отказ обнаружен еще до инициации асинхронной соответствующей операции, сервер возбудит исключение ESocketError, которое можно обработать точно так же.


 
ZV ©   (2010-09-14 16:43) [60]

Получается что если клиент  неожиданно  разорвал связь и пытается повторить соединение  то в этом обработчике нужно закрыть сокет
If (Error.ClassName = "ESocketError") then
  Begin
    If (Error.ClassName = "ESocketError") then
  Begin

ServerSocket1.Close.;

  end
else Application.ShowException(Error)

Сервер закроет сокет с которым возникает конфликт , а клиент все таки подключиться или ему после этого повторно нужно подключаться?


 
Сергей М. ©   (2010-09-14 21:56) [61]


> Сервер закроет сокет с которым возникает конфликт


Ну да, закроет.
Зачем ему нужно несуществующее соединение ?
Не нужно оно ему.


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


вот когда он подключится - тогда и разговор будет.

Тогда и новое OnClientConnect будет возбуждено.


 
ZV ©   (2010-09-15 09:23) [62]

Что то не хрена не получается устранить ошибку при повторном подключении клиента после обрыва связи
Вот что написал в обработчике ошибок
procedure TForm5.ServerSocket1ClientError(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
 Memo1.Lines.Text:=" Ошибка!!!" ;
 ServerSocket1.Socket.Connections[ServerSocket1.Socket.ActiveConnections-1].Close;

 end;

И в этом
procedure TForm5.ClException(Sender: TObject; Error: Exception);
begin
 If (Error.ClassName = "ESocketError") then
   Begin
     Memo1.Lines.Add("Ошибка!!! ");
    ServerSocket1.Socket.Connections[ServerSocket1.Socket.ActiveConnections].Close;
   end
 else Application.ShowException(Error);  
end;

Толку нет, сервер вылетает с ошибкой сокета

Как с этим бороться ?
Что делаю не правильно ?


 
Anatoly Podgoretsky ©   (2010-09-15 10:06) [63]

> ZV  (15.09.2010 09:23:02)  [62]

А что это значит [ServerSocket1.Socket.ActiveConnections].


 
ZV ©   (2010-09-15 11:43) [64]


> А что это значит [ServerSocket1.Socket.ActiveConnections].

Ну типа отключить того кто пытается подключиться. Что советуют то и делаю
Ну не знаю я что делать в обработчике ошибки.
Только что проверял чужой сервер на резкий обрыв связь и повторное подключения работает безотказно.
Значит можно решить эту проблему, но как?


 
Anatoly Podgoretsky ©   (2010-09-15 12:09) [65]

Я не поленился и просмотре все обсуждение, никто такого не советовал.


 
Anatoly Podgoretsky ©   (2010-09-15 12:11) [66]

Ищем не там где потерял, а там где светло.


 
Сергей М. ©   (2010-09-15 12:15) [67]


> отключить того кто пытается подключиться


А чем он провинился ?)


 
ZV ©   (2010-09-15 13:01) [68]

Ну так что делать в обработчике ошибок когда клиент пытается подключится после обрыва связи? И почему возникает ошибка .Если бы не эта хрень то все работает нормально.


 
Anatoly Podgoretsky ©   (2010-09-15 13:12) [69]

> Сергей М.  (15.09.2010 12:15:07)  [67]

Диверсант.


 
Сергей М. ©   (2010-09-15 13:51) [70]


> ZV ©   (15.09.10 13:01) [68]


Обработчик OnClientError не вызывается при копвтке коннекта, не выдумывай небылиц.


 
ZV ©   (2010-09-15 14:17) [71]

Я не знаю что где вызывается. Но в мемо1 OnClientError надпись выводит значит срабатывает  так же как и процедура ClException.

Но это все не главное . Вопрос остается открытым - Что делать?
При повторном подключении оборвавшегося клиента  сервер падает.


 
Сергей М. ©   (2010-09-15 14:24) [72]


> Я не знаю что где вызывается


Ну вот теперь будешь знать)


> в мемо1 OnClientError надпись выводит


А ты убери полностью всю требуху из OnClientConnect/Disconnect/Read/Write и удивись - никто никакие надписи никуда выводить не будет)


 
ZV ©   (2010-09-15 15:31) [73]

Зачем что то убирать , все нормально работает. Вы наверно не поймете в чем проблема, я постараюсь объяснить. В качестве клиентов выступают микроконтроллеры они коннектятся к серверу и получают от него нужную информацию . Когда микроконтроллеру не нужно получать информацию он отключается от сервера а когда нужно опять подключается. Все это на данный момент работает  к сервер одновременно подключено  78 клиентов. Нормально происходит авторизация доступа к серверу и отключение не нужных клиентов.

Но если взять и отключить питание клиенту(микроконтроллеру) подключенному к серверу , то он перезагружается и снова коннектися к серверу и вот тут сервер дает сбой в виде ошибки сокета . Я так думаю это происходит потому что произошел обрыв связи и соединение не было закрыто как положено, и при повторном подключении этого же клиента,  сервер падает.
Те клиенты которые отключились самостоятельно нормально подключаются снова и работают с сервером.
 
Только не надо спрашивать а зачем отключать питание и т.д.


 
Сергей М. ©   (2010-09-15 15:54) [74]


> коннектися к серверу и вот тут сервер дает сбой в виде ошибки
> сокета


Т.е. ты утверждаешь что при этом OnClientConnect не возникает, а вместо него с какого-то перепугу возникает OnClientError ?

Ты готов кровью поклясться в истинности своего утверждения ?)


 
ZV ©   (2010-09-15 16:41) [75]

Вот какая складывается ситуация
При повторном подключении клиента у меня выскакивают сообщения
Asynchronous Socket error 10053  я игнорирую сообщение и нажимаю кнопку дальше и смотрю какие сообщения и от каких процедур  появилось в поле Мемо

вот что я вижу

Ошибка!!! (1)
[15:09:17]Клиент отключился IP-172.17.226.1 (2)
Ошибка!!! Повторное подключение (3)
[15:09:17]Подключился клиент (4)

1-сообщение от ServerSocket1ClientError(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);

2-сообщение от ServerSocket1ClientDisconnect(Sender: TObject; Socket:TCustomWinSocket);

3-сообщение от ClException(Sender: TObject; Error: Exception);)

4-сообщение от ServerSocket1ClientConnect(Sender: TObject;
 Socket: TCustomWinSocket);

Сергей М. Вы правы клиент все таки подключился , и вроде бы  работал.
Но что делать с выпадающим окном с сообщением об ошибке, в чем причина появления этого сообщения


 
Anatoly Podgoretsky ©   (2010-09-15 16:45) [76]

Разберись, что ошибка 10053 значит.


 
Anatoly Podgoretsky ©   (2010-09-15 16:46) [77]

И зачем ты игнорируешь, или раз ты не можешь работать с ассинхронными сокетами, то перейди на синхронные. Без знаний работа с с ассинхронными сокетами безперспективна.


 
Сергей М. ©   (2010-09-15 16:55) [78]


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


Ну наконец-то)
Теперь, полагаю, ты осознал что ошибку вызывает не факт подключения, а кривые действия твоего сервера уже после успешного подключения ?

Вот я тебе и предлагаю - чтобы лишний раз убедиться в этом, выкинь требуху изо всех обработчиков кроме OnClientConnect и OnClientDisconnect, оставив в них только протоколирование возникновения этих событий.
Событие OnClientError не должно возникнуть ни разу на всем протяжении времени пока сервер активен.


 
Сергей М. ©   (2010-09-15 17:09) [79]


> ZV ©   (15.09.10 16:41) [75]


Ты пойми одну простую вещь - OnClientError не может возникнуть, если сервер не производит никаких операций с соединением, ассоциированным с ранее подключившимся клиентом (т.е. фигурирующим в списке Connections). К этим действиям относятся вызовы сервером любых Send- и Receive-методов, а также метода Close объекта TServerClientWinSocket, коим клиент представлен в списке Connections.


 
ZV ©   (2010-09-15 17:19) [80]


> ошибку вызывает не факт подключения, а кривые действия твоего
> сервера уже после успешного подключения ?
>

Да не тут все не так, вы посмотрите внимательно на последовательность появления сообщений, сперва идет обработка ошибок а затем подключение . У меня в обработчиках ошибок ни чего кроме вывода сообщения нет.
Вот что пишут об этой ошибке (автоматический перевод с англ)


WSAECONNABORTED (10053) Программное обеспечение вызвало связи Прервать.

Беркли Описание: прервать соединение было вызвано внутренними на вашей машине. Программное обеспечение вызвало связи прервать из-за отсутствия места на очереди сокета и сокета не может принимать новые соединения.

WinSock описание: Частично же, как и Беркли. Ошибка может возникать при локальной вычислительной сети прерывает соединение. Это может произойти, если WinSock прервалось после установленного соединения ретрансляции данных не удается (получатель никогда не признает данные, передаваемые на поток данных сокета).

TCP / IP сценарий: соединение будет таймаут, если местная система не получает (ACK) nowledgement для переданных данных. Было бы также, если тайм-аут (FIN) иш пакетов TCP не ACK"d (и даже если это FIN ACK"d, в конечном счете, если тайм-аут FIN не возвращается).

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

 Пинг удаленного хоста вы были связаны. Если он не отвечает, это может быть офф-лайн или могут быть проблемы в сети на этом пути. Если это не реагировать, то эту проблему можно было бы переходных 1 (так что вы можно восстановить в настоящее время), или сервер приложений вы подключены к бы прекращено (так что вы не сможете подключиться снова).
   ) Пинг местного узла, чтобы проверить вашу локальную сеть продолжает функционировать (если на последовательный порт, см. следующий шаг)
    Если вы на последовательный порт, локальный маршрутизатор IP-адрес хоста, который первоначально вошли на с SLIP или PPP.
  Пинг хоста на той же подсети, что и хозяин вы подключены к (если вы знаете, 1). Это позволит убедиться, что сеть не функционирует.
  Попробуйте "Traceroute" принимающей вы подключены. Это не будет раскрывать слишком много, если вы не знаете адреса маршрутизатора на удаленной машине, но это может помочь определить, что проблема находится где-то в пути.

Функции: Recv () , recvfrom () , SendTo () , Fd_Close
Дополнительные функции: отправить () с CAN также WSAECONNABORTED Fail. Любая функция, как входной разъем, который принимает параметр - за исключением Закрыть сокет () - Неужели это возможно к ошибке.


оригинал здесь http://www.sockets.com/err_lst1.htm



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

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

Наверх





Память: 0.64 MB
Время: 0.108 c
2-1284621331
JohnKorsh
2010-09-16 11:15
2010.12.12
Можно ли средствами Delphi создать WiFi Ad-Hock сеть?


2-1284977449
123456
2010-09-20 14:10
2010.12.12
работа с treeview


3-1248979662
Sysdba
2009-07-30 22:47
2010.12.12
Проблема начинающего с Interbase/Firebird


2-1284702790
vlgrig1961
2010-09-17 09:53
2010.12.12
SubStr и поле типа long?


15-1283723936
Германн
2010-09-06 01:58
2010.12.12
Иконка контроллера





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