Что нового

[Сеть, интернет] Активация клиента при появлении сервера в сети.

SlavaS

Знающий
Сообщения
35
Репутация
5
Все доброго времени суток. Помогите пожалуйста решить одну проблемку.
Необходимо чтобы клиент, при отключении от сервера, переходил в режим ожидания (статус "Listening"), и соединялся с сервером при его появлении в сети (т.е. переходил в статус "Established"). А также чтобы появившиеся клиенты в сети, при запущенном сервере, также автоматом соединялись с ним.

Если оставить TCPConnect, тогда комп начинает очень сильно глючить, и через некоторое время пропадает инет, а также ооочень долго открываются офисовские документы (doc, xls и т.д.). Такое происходит в XP, в 7 вроде такого не замечал. Мне кажется что это происходит из-за того что порт находится в состоянии "Send", или из-за таймаута TCPConnect.

В данный момент получается активировать клиентов только вручную, отсылкой сообщения от сервера на клиент. Но как это все автоматизировать? Возможно конечно что я делаю что-то не так как нужно, готов выслушать все замечания :smile:. Прошу прощения если что не так, пишите обязательно исправлюсь ;)

Вот мои примерчики

Клиент
Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $IPADDRESS = @IPAddress1; IP сервера
Global $PORT = 65432

$Form1 = GUICreate("Client", 180, 80, 100, 100, $WS_SYSMENU)
$Label = GUICtrlCreateLabel("Disconnected", 16, 16, 120, 28)
GUICtrlSetFont(-1, 14, 400, 0)
GUICtrlSetColor(-1, 0xff0000)
GUISetState(@SW_SHOW)

TCPStartup()

While 1

	$MainSocket = TCPListen(@IPAddress1, 65431)
	If $MainSocket = -1 Then ContinueLoop

	Do
		$ConnectedSocket = TCPAccept($MainSocket)
	Until $ConnectedSocket <> -1

	$anweisung = TCPRecv($ConnectedSocket, 2048)
	If @error Or $anweisung <> "HELLO" Then
		TCPCloseSocket($ConnectedSocket)
		TCPCloseSocket($MainSocket)
		ContinueLoop
	EndIf

	TCPCloseSocket($ConnectedSocket)
	TCPCloseSocket($MainSocket)
	Sleep(1000)

	$ConnectedSocket = TCPConnect($IPADDRESS, $PORT)
	If @error Then ContinueLoop


	GUICtrlSetData($Label, "Connected")
	GUICtrlSetColor(-1, 0x00ff00)
	$tcpcheck = 1
	While 1
		$anweisung = TCPRecv($ConnectedSocket, 2048)
		If @error Then
			TCPCloseSocket($ConnectedSocket)
			GUICtrlSetData($Label, "Disconnected")
			GUICtrlSetColor(-1, 0xff0000)
			$tcpcheck = 0
			ContinueLoop 2
		EndIf
	WEnd
WEnd

If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)
TCPShutdown()

Сервер
Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $IPADDRESS = @IPAddress1 ;IP клиента
Global $PORT = 65432

$Form1 = GUICreate("Server", 230, 100, -1, -1, $WS_SYSMENU)
$Button = GUICtrlCreateButton("Connect", 32, 24, 169, 33)
GUISetState(@SW_SHOW)

TCPStartup()

$MainSocket = TCPListen($IPADDRESS, $PORT)
If $MainSocket = -1 Then Exit

While 1

	$ConnectedSocket = TCPAccept($MainSocket)
	If @error Then ContinueLoop

	$msg = GUIGetMsg()
	Switch $msg
		Case $GUI_EVENT_CLOSE
			ExitLoop
		Case $Button
			_test_connect()
	EndSwitch
WEnd

If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)
TCPShutdown()

Func _test_connect()
	$TestConnectedSocket = TCPConnect($IPADDRESS, 65431)
	TCPSend($TestConnectedSocket, "HELLO")
	TCPCloseSocket($TestConnectedSocket)
	$TestConnectedSocket = -1
EndFunc   ;==>_test_connect
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Используй подобные конструкции в основном цикле:
Код:
Global $_aServer = StringSplit( ..., ':') ;ip:port
Global $_szIP = TCPNameToIP( $_aServer[1] ), $_iPing
Do
	$_iPing = Ping( $_szIP )
	While ($_iPing <> 0)
		$_hSocket = TCPConnect($_szIP, $_aServer[2])
		If @Error Then _
			ExitLoop

		Do
			$_vRecv = _PackageRecv( )
			If Not @Error And $_vRecv <> '' Then
				...
			EndIf
			If @Error Then
				TCPCloseSocket( $_hSocket )
				ExitLoop
			EndIf
		Until False
		; ---
		$_iPing = 0 ;Reset current
	WEnd

	;$_szIP = TCPNameToIP( $_aServer[1] ) ;Refresh
	Sleep( ... * 1000 ) ;Время в секундах до попытки возобновить соединение
Until False


Если же требуется, что бы скрипт не "останавливал" работу с GUIGetMsg в основном цикле, то можешь сделать примерно так:
Код:
Global $_hSocket = 0
Global $_aServer = StringSplit( ..., ':') ;ip:port
Global $_szIP = TCPNameToIP( $_aServer[1] ), $_iPing


While 1
	$_hMsg =  GUIGetMsg()
	Switch $_hMsg
		...
	EndSwitch

	If $_hSocket Then
		$_vRecv = _PackageRecv( )
		If Not @Error And $_vRecv <> '' Then
			...
		ElseIf @Error Then
			TCPCloseSocket( $_hSocket )
			$_hSocket = 0
		EndIf
	Else
		$_iPing = Ping( $_szIP )
		If $_iPing <> 0 Then
			$_hSocket = TCPConnect($_szIP, $_aServer[2])
			If @Error Then
				$_hSocket = 0
			EndIf
		EndIf
	EndIf
WEnd
 
Автор
S

SlavaS

Знающий
Сообщения
35
Репутация
5
с пингом не вариант, т.к. комп всегда включен. Когда запускаем серверную часть, вот тогда клиент и должен подключатся.
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
:shok: что за.... почему сервер конектиться к клиенту?
OffTopic:
Сломай систему?
 
Автор
S

SlavaS

Знающий
Сообщения
35
Репутация
5
что за.... почему сервер конектиться к клиенту?
он не конектится, а уведомляет клиентов что доспупен для подключения, вот клиенты уже конектятся к нему
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Как вариант на сервере расшарить папку и на клиенте проверять наличия в ней определенных файлов.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
SlavaS [?]
он не конектится, а уведомляет клиентов что доспупен для подключения, вот клиенты уже конектятся к нему
Можно еще разместить на сервере скажем ini файл, в котором будет уведомляться - доступен ли сервер для подключения или нет, а клиенты будут периодически его скачивать.

Хотя наиболее простой вариант тот, что предоставил я. Ибо как вы еще планируете уведомлять клиентов, адреса которых не знаете.
 
Верх