Что нового

[Сеть, интернет] Слетает соединение TCP после ждущего режима на клиенте.

Юрий

Новичок
Сообщения
82
Репутация
3
Доброго времени суток. Написал программу в свой класс информатики, которая служит для перевода ученических компьютеров в спящий, ждущий режими и выключение. Действует по системе "Клиент - Сервер", в которой клиент работает только в приём (если это важно). Использовались стандартные функции TCP. Но после перевода клиента в ждущий режим и соответственно пробуждения слетает так сказать "соединительный мост" (то есть сокет уходит во своя си) и дальше до клиента командлы не доходят. Вот исходники: (написал вроде как аккуратно и приемлемо для чтения)

Сервер:
Код:
;~ Библиотеки и опции ~;
TraySetIcon("shell32.dll" , 18)
TraySetToolTip( "Сетевой помощник - Учитель" )
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode" , 3)      ; всякие опции и настройки
TCPStartup()

;~ Трей ~;
$TrayShutDown = TrayCreateItem( "Выключить компьютеры" )       ; создание трей-меню
$TraySleep = TrayCreateItem( "Ждущий режим" )
$TrayHibernate = TrayCreateItem( "Спящий режим" )
TrayCreateItem( "" )
$TrayExit = TrayCreateItem( "Выход" )
   TrayItemSetOnEvent( $TrayShutDown , "_TrayEvent" )
   TrayItemSetOnEvent( $TraySleep , "_TrayEvent" )
   TrayItemSetOnEvent( $TrayHibernate , "_TrayEvent" )
   TrayItemSetOnEvent( $TrayExit , "_TrayEvent" )
   
TraySetState()

;~ Переменные ~;
Local $ConnectedSockets[300] , $FreeSocket = 0      ; объявляем переменные
Local $MainSocket = TCPListen( @IPAddress1 , 33891 )      ; думаю, что по их названиям всё и так понятно
For $i = 0 To 299
   $ConnectedSockets[$i] = -1
Next

;~ Функции ~;
_Main()

Func _Main()
   While 1
	  If $ConnectedSockets[$FreeSocket] = -1 Then    ; поятоянно разрешаем подключение к последнему сокету
		 $ConnectedSockets[$FreeSocket] = TCPAccept( $MainSocket )          ; который отдельный для каждого клиента
	  Else
		 $FreeSocket = $FreeSocket + 1
	  EndIf
	  Sleep(10)
   WEnd
EndFunc

Func _TrayEvent()             ; следим за треем
   Select
   Case @TRAY_ID = $TrayShutDown
	  _Send("ShutDown")
   Case @TRAY_ID = $TraySleep
	  _Send("Sleep")
   Case @TRAY_ID = $TrayHibernate
	  _Send("Hibernate")
   Case @TRAY_ID = $TrayExit
	  _Send("Exit")
	  Beep(1000,100)
	  Sleep(10)
	  Beep(900,100)
	  Sleep(10)
	  Beep(800,100)  
	  TCPShutdown()
	  Exit
   EndSelect
EndFunc

Func _Send( $msg )   ; рассылка команд клиентам
   For $i = 0 To $FreeSocket - 1
	  TCPSend( $ConnectedSockets[$i] , $msg )
   Next
   If $msg <> "Exit" Then TrayTip( "Сетевой помощник" , "Готово!" , 2 )
EndFunc

While 1
   Sleep(1000000000)
WEnd

Клиент:
Код:
;~ Библиотеки и Опции ~;
TraySetIcon("shell32.dll" , 18)
TraySetToolTip( "Сетевой помощник - Ученик" )
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode" , 3)
Opt("TCPTimeout" , 50)     ; всякие опции и настройки
TCPStartup()

;~ Трей ~;
$TraySetIP = TrayCreateItem( "Сменить IP сервера" )
TrayCreateItem( "" )
$TrayExit = TrayCreateItem( "Выход" )                  ; пишем трей-меню
   TrayItemSetOnEvent( $TraySetIP , "_TrayEvent" )
   TrayItemSetOnEvent( $TrayExit , "_TrayEvent" )
   
TraySetState()

;~ Переменные ~;
Local $ConnectedSocket = -1 , $RecvMsg , $IP = IniRead(@ScriptDir & "\IP.ini" , "IP" , "IP" , "None")        ; объявляем
If $IP = "None" Then  ; проверяем наличие ip сервера                                                         ; переменные
   Local $NewIP = InputBox( "Сетевой помощник" , "Введите новый IP адресс сервера" , "10.1.1.100" )
   If $NewIP <> "" Then
	  $IP = $NewIP
	  IniWrite(@ScriptDir & "\IP.ini" , "IP" , "IP" , $NewIP)
	  TrayTip("Сетевой помощник" , "Принято!" , 2)
   EndIf
EndIf

$ConnectedSocket = TCPConnect( $IP , 33891 )   ; подключение к серверу
If $ConnectedSocket = -1 Then
   MsgBox(16 , "Сетевой помощник" , "Ошибка подключения к серверу!" , 2)
   Exit
Else
   TrayTip("Сетевой помощник" , "Подключение установлено!" , 2)
EndIf

;~ Функции ~;
_Main()

Func _Main()
   While 1    ; ожидание сообщения по TCP
	  $Recv = TCPRecv( $ConnectedSocket , 256 )
	  If $Recv <> "" Then
		 Select
		 Case $Recv = "ShutDown"
			_Beep()
			Shutdown(1)
		 Case $Recv = "Sleep"
			_Beep()
			Shutdown(32)
		 Case $Recv = "Hibernate"
			_Beep()
			Shutdown(64)
		 Case $Recv = "Exit"
			_Beep()
			Exit
		 EndSelect
	  EndIf
	  Sleep(10)
   WEnd
EndFunc
   
Func _TrayEvent() ; трей-функция, для разбора полётов
   Select
   Case @TRAY_ID = $TraySetIP
	  Local $NewIP = InputBox( "Сетевой помощник" , "Введите новый IP адресс сервера" , $IP )
	  If $NewIP <> "" Then
		 $IP = $NewIP
		 IniWrite(@ScriptDir & "\IP.ini" , "IP" , "IP" , $NewIP)
		 TrayTip("Сетевой помощник" , "Принято!" , 2)
		 ; Обновляем подключение
		 $ConnectedSocket = TCPConnect( $IP , 33891 )
		 If $ConnectedSocket = -1 Then
			MsgBox(16 , "Сетевой помощник" , "Ошибка подключения к серверу!" , 2)
			Exit
		 EndIf
	  EndIf
   Case @TRAY_ID = $TrayExit  
	  _Beep()  
	  Exit
   EndSelect
EndFunc

Func _Beep()
   Beep(1000,100)
   Sleep(10)
   Beep(900,100)
   Sleep(10)
   Beep(800,100) 
EndFunc

While 1
   Sleep(10000000)
WEnd
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Я так думаю, что если человек в своих сриптах вообще не проверяет наличие ошибок после вызовов функций, то этот человек крутой программист.
А давать советы крутому программисту как-то... Нетактично что ли...
 
Автор
Юрий

Юрий

Новичок
Сообщения
82
Репутация
3
Я так думаю, что если человек в своих сриптах вообще не проверяет наличие ошибок после вызовов функций, то этот человек крутой программист.
А давать советы крутому программисту как-то... Нетактично что ли...

Понял, согласен. Но как ввести проверку сокета со стороны клиента? Запускал прогу и вырубал сервер оставляя клиента, при этом он (кл.) постоянно писал в консоль SciTE параметр $ConnectedSocket
Код:
ConsoleWrite($ConnectedSocket & " ")

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

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Посмотри
http://autoit-script.ru/autoit3_docs/functions/TCPSend.htm
http://autoit-script.ru/autoit3_docs/functions/TCPRecv.htm

Видишь после каждой попытки получить/отправить сообщение идёт
Код:
If @error Then



Добавлено:
Сообщение автоматически объединено:

Если интресно, посмотри мои изыскания
http://autoit-script.ru/index.php/topic,11436.0.html
как видишь, на сервере я держу массив сокетов и массив флагов подключенности сокетов.
Если при приёме/передаче возникает ошибка, то флаг сбрасывается
и при следующем проходе цикла сервер снова пытается соединить с этим клиентом.
 
Автор
Юрий

Юрий

Новичок
Сообщения
82
Репутация
3
Решил проблему внедрением в клиента функции через Adlibregister, что бы та каждые 20 сек. спрашивала у сервера здесь ли он, а тот, соответственно, отвечал. Спасибо всем большое)
 
Верх