Что нового

[Сеть, интернет] Непонятная ошибка в получении/передачи пакетов (TCP)

Dream-52

...
Сообщения
82
Репутация
1
Доброго времени суток))
Весь день возился с кодом....но так и ошибку не могу найти - проверял не один десяток раз! Проблема в том,что когда выделяю айпи в гуи - ничего не происходит...
Гляньте пожалуйста,в чем может быть проблема ? :wacko: :wacko: :wacko: голова кругом.

Чувствую,что решение гдето рядом...

Будущий сервер :

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>

$IP = '192.168.0.1'
$port = 59888
Global $aSockets, $i, $rep, $MainSocket, $socket, $result, $IP, $port, $ipBotOld



$GUI = GUICreate("Server", 970, 618, 108, 292)
$GenGUI = GUICtrlCreateList("", 0, 0, 820, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$BotsGUI = GUICtrlCreateList("", 820, 0, 149, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$InputString = GUICtrlCreateEdit("", 0, 568, 969, 49, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL))

GUICtrlSetFont($GenGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($BotsGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($InputString, 12, 200, 1, "Georgia")

GUISetState(@SW_SHOW)

TCPStartup()

$MainSocket = TCPListen($IP, $port, 1000) ;Создаем слушающий сокет, по указанному адресу

Dim $aSockets[1] = [0]


While 1

	$MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
	$result = ReceiveData($MainSocket_A) ;проверяем входящее соединение на наличие пакета
	If $result = '' Or $result = '0' Then

	Else

		$SocketToIp = SocketToIP($MainSocket_A)
		GUICtrlSetData($BotsGUI, $SocketToIp)
		GUICtrlSetData($GenGUI, ' ' & $SocketToIp & ' >> ' & $result)
		Sleep(100)
		TCPCloseSocket($MainSocket_A);Закрываем сокет

	EndIf


	$ipBot = GUICtrlRead($BotsGUI)
	If $ipBot = '' Or $ipBot = $ipBotOld Then
	Else

		GUICtrlSetData($GenGUI, 'запрос данных...')
		MsgBox(16, '', $ipBot & ':' & $port)
		$socket = TCPConnect($ipBot, $port)
		TCPSend($socket, 'ping')
		Sleep(100)
		TCPCloseSocket($socket)
		$ipBotOld = $ipBot
	EndIf

	Sleep(100)

WEnd


TCPShutdown()



Func SendingData($MainSocket_A0, $data)
	$socket = TCPConnect(SocketToIP($MainSocket_A0), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
	Return TCPSend($socket, $data);Отправляем данные на сервер
	Sleep(100)
	TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func ReceiveData($ConnectedSocket)

	If $ConnectedSocket <> -1 Then
		$aSockets[0] += 1
		ReDim $aSockets[$aSockets[0] + 1]
		$aSockets[$aSockets[0]] = $ConnectedSocket
	EndIf

	For $i = 1 To $aSockets[0]
		Return TCPRecv($aSockets[$i], 256, 0)
		If @error Then
			TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

			For $j = $i To $aSockets[0] - 1
				$aSockets[$j] = $aSockets[$j + 1]
			Next
			$aSockets[0] -= 1
			ReDim $aSockets[$aSockets[0] + 1]

			ContinueLoop 2
		EndIf
		Sleep(5)
	Next

EndFunc   ;==>ReceiveData

Func SocketToIP($SHOCKET)
	Local $sockaddr, $aRet
	$sockaddr = DllStructCreate("short;ushort;uint;char[8]")

	$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
			"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
	If Not @error And $aRet[0] = 0 Then
		$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
		If Not @error Then $aRet = $aRet[0]
	Else
		$aRet = 0
	EndIf
	$sockaddr = 0

	Return $aRet
EndFunc   ;==>SocketToIP

Будущий клиент :

Код:
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_UseUpx=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup();Инициировать использование службы TCP
$nIP = '192.168.0.6' ;адресс сервера
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
$port = 59888 ;Указываем порт к которому будем подключаться
$tTime = TimerInit()
Do
	$socket = TCPConnect('192.168.0.1', $port);Указыываем ОС создать сокет, подключенный к указанному адресу
Until $socket <> -1

TCPSend($socket, @ComputerName & ' онлайн (в сети уже ' & TimerDiff($tTime) / 1000 & ')');Отправляем данные на сервер
Sleep(100)
TCPCloseSocket($socket)
Sleep(100)
$MainSocket = TCPListen($nIP, $port, 2) ; создаем прослушивающий СОКЕТ


While 1

	$ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
	If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета

		While 1
			$result = TCPRecv($ConnectedSocket, 2048)
			If $result <> '' Then ;если данные есть,то принимаем первые 2048

				If $result = 'ping' Then
					MsgBox(16, '', 'ping : yes')
					$socket = TCPConnect(SocketToIP($ConnectedSocket), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
					Sleep(1000)
					SocketToIP($ConnectedSocket)
					Sleep(1000)
					TCPSend($socket, "time " & @MDAY & "-" & @MON & "-" & @YEAR & "  /  " & @HOUR & ":" & @MIN & ":" & @SEC)

					Sleep(1000)
					TCPCloseSocket($socket)

				EndIf

				Sleep(25)
			Else
				ExitLoop
			EndIf
		WEnd

	EndIf

	Sleep(200)

WEnd


TCPShutdown();Завершить использование службы TCP


Func SendingData($MainSocket_A0, $data)
	$socket = TCPConnect(SocketToIP($MainSocket_A0), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
	Return TCPSend($socket, $data);Отправляем данные на сервер
	Sleep(100)
	TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func SocketToIP($SHOCKET)
	Local $sockaddr, $aRet
	$sockaddr = DllStructCreate("short;ushort;uint;char[8]")

	$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
			"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
	If Not @error And $aRet[0] = 0 Then
		$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
		If Not @error Then $aRet = $aRet[0]
	Else
		$aRet = 0
	EndIf
	$sockaddr = 0

	Return $aRet
EndFunc   ;==>SocketToIP
 

Renz

Осваивающий
Сообщения
63
Репутация
36
А окно сообщения выходит с ip и портом?
затем: "запрос данных....."?
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
Ой,не совсем понял.Получается так.Когда происходит запрос данных (тоесть когда я выбираю айпи в списке),то клиенту шлется команда 'ping' и клиент потом отсылает серверу пакет (TCPSend) , но сервер почемуто его не ....видит или что,не пойму...
 

Renz

Осваивающий
Сообщения
63
Репутация
36
Сначала проверил на 1 лок.компе приходит сообщение отправленное отсюда:(сервер)
Код:
GUICtrlSetData($GenGUI, ' ' & $SocketToIp & ' >> ' & $result)

Затем на 2 компах получается что что клиент не видит входящее сообщение здесь:
Код:
$ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета
		$result = TCPRecv($ConnectedSocket, 2048)
        While 1
            
            If $result <> '' Then ;если данные есть,то принимаем первые 2048

                ;If $result = 'ping' Then
                    MsgBox(16, '', 'ping : yes')
                    $socket = TCPConnect(SocketToIP($ConnectedSocket), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
                    Sleep(1000)
                    SocketToIP($ConnectedSocket)
                    Sleep(4000)
					;
                    TCPSend($socket, "time " & @MDAY & "-" & @MON & "-" & @YEAR & "  /  " & @HOUR & ":" & @MIN & ":" & @SEC)

                    Sleep(1000)
                    TCPCloseSocket($socket)

                ;EndIf

                Sleep(25)
            Else
                ExitLoop
            EndIf
        WEnd

    EndIf

Получается нужно искать ошибку в клиенте.Я пока не нашел :wacko:
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
Cтранно...я думал это просто как обычно , моя невнимательность .
 

Renz

Осваивающий
Сообщения
63
Репутация
36
Код:
$ConnectedSocket = TCPAccept($MainSocket)

возвращает -1
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
Ух ты....странно...буду думать....
 

Renz

Осваивающий
Сообщения
63
Репутация
36
все заработало ! :laugh:

сервер:
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>

$IP = '192.168.0.91'
$port = 59888
Global $aSockets, $i, $rep, $MainSocket, $socket, $result, $IP, $port, $ipBotOld
Func SendingData($MainSocket_A0, $data)
    $socket = TCPConnect(SocketToIP($MainSocket_A0), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
    Return TCPSend($socket, $data);Отправляем данные на сервер
    Sleep(100)
    TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func ReceiveData($ConnectedSocket)

    If $ConnectedSocket <> -1 Then
        $aSockets[0] += 1
        ReDim $aSockets[$aSockets[0] + 1]
        $aSockets[$aSockets[0]] = $ConnectedSocket
    EndIf

    For $i = 1 To $aSockets[0]
        Return TCPRecv($aSockets[$i], 256, 0)
        If @error Then
            TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

            For $j = $i To $aSockets[0] - 1
                $aSockets[$j] = $aSockets[$j + 1]
            Next
            $aSockets[0] -= 1
            ReDim $aSockets[$aSockets[0] + 1]

            ContinueLoop 2
        EndIf
        Sleep(5)
    Next

EndFunc   ;==>ReceiveData

Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP


$GUI = GUICreate("Server", 970, 618, 108, 292)
$GenGUI = GUICtrlCreateList("", 0, 0, 820, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$BotsGUI = GUICtrlCreateList("", 820, 0, 149, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$InputString = GUICtrlCreateEdit("", 0, 568, 969, 49, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL))

GUICtrlSetFont($GenGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($BotsGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($InputString, 12, 200, 1, "Georgia")

GUISetState(@SW_SHOW)

TCPStartup()

$MainSocket = TCPListen($IP, $port, 1000) ;Создаем слушающий сокет, по указанному адресу

Dim $aSockets[1] = [0]


While 1

    $MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    $result = ReceiveData($MainSocket_A) ;проверяем входящее соединение на наличие пакета
    If $result = '' Or $result = '0' Then

    Else

        $SocketToIp = SocketToIP($MainSocket_A)
        GUICtrlSetData($BotsGUI, $SocketToIp)
        GUICtrlSetData($GenGUI, ' ' & $SocketToIp & ' >> ' & $result)
        Sleep(100)
        TCPCloseSocket($MainSocket_A);Закрываем сокет

    EndIf


    $ipBot = GUICtrlRead($BotsGUI)
    If $ipBot = '' Or $ipBot = $ipBotOld Then
    Else

        GUICtrlSetData($GenGUI, 'запрос данных...')
        MsgBox(16, '', $ipBot & ':' & $port)
		;Sleep(4000)
        $socket = TCPConnect($ipBot, $port)
		MsgBox(16, '$socket', $socket)
        TCPSend($socket, 'ping')
        Sleep(100)
        TCPCloseSocket($socket)
        $ipBotOld = $ipBot
    EndIf

    Sleep(100)

WEnd


TCPShutdown()


клиент:
Код:
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_UseUpx=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup();Инициировать использование службы TCP
$nIP = '192.168.0.91' ;адресс сервера
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
$port = 59888 ;Указываем порт к которому будем подключаться
$tTime = TimerInit()
Do
    $socket = TCPConnect('192.168.0.91', $port);Указыываем ОС создать сокет, подключенный к указанному адресу
Until $socket <> -1

TCPSend($socket, @ComputerName & ' онлайн (в сети уже ' & TimerDiff($tTime) / 1000 & ')');Отправляем данные на сервер
Sleep(100)
TCPCloseSocket($socket)
Sleep(100)
Global $MainSocket,$nIPmy='192.168.0.68'
$MainSocket = TCPListen($nIPmy, $port, 1000) ; создаем прослушивающий СОКЕТ
msgbox(0,"$MainSocket",$MainSocket)
Func SendingData($MainSocket, $data)
    $socket = TCPConnect(SocketToIP($MainSocket), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
    ;Return TCPSend($socket, $data);Отправляем данные на сервер
	TCPSend($socket, $data);Отправляем данные на сервер
    Sleep(100)
    TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP

While 1

    $ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
	;msgbox(0,"$ConnectedSocket",$ConnectedSocket)
	If $ConnectedSocket >= 0 Then
    msgbox(0,"","my server - Client Connected")
    EndIf
    If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета
		$result = TCPRecv($ConnectedSocket, 2048)
		MsgBox(16, '', $result)
        While 1
            
            If $result <> '' Then ;если данные есть,то принимаем первые 2048

                ;If $result = 'ping' Then
                    MsgBox(16, '', 'ping : yes')
                    $socket = TCPConnect(SocketToIP($ConnectedSocket), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
                    Sleep(1000)
                    SocketToIP($ConnectedSocket)
                    Sleep(4000)
					;
                    TCPSend($socket, "time " & @MDAY & "-" & @MON & "-" & @YEAR & "  /  " & @HOUR & ":" & @MIN & ":" & @SEC)

                    Sleep(1000)
                    TCPCloseSocket($socket)

                ;EndIf

                Sleep(25)
            Else
                ExitLoop
            EndIf
        WEnd

    EndIf

WEnd


TCPShutdown();Завершить использование службы TCP


Ненужное сам уберешь

Ошибка была в ip на клиенте :
Код:
Global $MainSocket,$nIPmy='192.168.0.68'
$MainSocket = TCPListen($nIPmy, $port, 1000) ; создаем прослушивающий СОКЕТ

клиент должен открывать свой порт
PS: Работает на разных копмах, если клиент и сервер на одном то не работает
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Скрипт переписывать не стал :wacko:
Просто убрал "любимые" слипы :smile:
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>

$IP = @IPAddress1
$SendPort = 65433
$RecvPort = 65432
Global $aSockets, $i, $rep, $MainSocket, $socket, $result, $IP, $port, $ipBotOld



$GUI = GUICreate("Server", 970, 618, 108, 292)
$GenGUI = GUICtrlCreateList("", 0, 0, 820, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$BotsGUI = GUICtrlCreateList("", 820, 0, 149, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$InputString = GUICtrlCreateEdit("", 0, 568, 969, 49, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL))

GUICtrlSetFont($GenGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($BotsGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($InputString, 12, 200, 1, "Georgia")

GUISetState(@SW_SHOW)

TCPStartup()

$MainSocket = TCPListen($IP, $RecvPort, 1000) ;Создаем слушающий сокет, по указанному адресу

Dim $aSockets[1] = [0]


While 1

    $MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    $result = ReceiveData($MainSocket_A) ;проверяем входящее соединение на наличие пакета
    If $result = '' Or $result = '0' Then

    Else

        $SocketToIp = SocketToIP($MainSocket_A)
        GUICtrlSetData($BotsGUI, $SocketToIp)
        GUICtrlSetData($GenGUI, ' ' & $SocketToIp & ' >> ' & $result)
        TCPCloseSocket($MainSocket_A);Закрываем сокет

    EndIf


    $ipBot = GUICtrlRead($BotsGUI)
    If $ipBot = '' Or $ipBot = $ipBotOld Then
    Else

        GUICtrlSetData($GenGUI, 'запрос данных...')
        MsgBox(16, '', $ipBot & ':' & $SendPort)
        $socket = TCPConnect($ipBot, $SendPort)
        TCPSend($socket, 'ping')
        TCPCloseSocket($socket)
        $ipBotOld = $ipBot
    EndIf

WEnd


TCPShutdown()



Func SendingData($MainSocket_A0, $data)
    $socket = TCPConnect(SocketToIP($MainSocket_A0), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
    Return TCPSend($socket, $data);Отправляем данные на сервер
    TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func ReceiveData($ConnectedSocket)

    If $ConnectedSocket <> -1 Then
        $aSockets[0] += 1
        ReDim $aSockets[$aSockets[0] + 1]
        $aSockets[$aSockets[0]] = $ConnectedSocket
    EndIf

    For $i = 1 To $aSockets[0]
        Return TCPRecv($aSockets[$i], 256, 0)
        If @error Then
            TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

            For $j = $i To $aSockets[0] - 1
                $aSockets[$j] = $aSockets[$j + 1]
            Next
            $aSockets[0] -= 1
            ReDim $aSockets[$aSockets[0] + 1]

            ContinueLoop 2
        EndIf
    Next

EndFunc   ;==>ReceiveData

Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP
Код:
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_UseUpx=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup();Инициировать использование службы TCP
$nIP = @IPAddress1 ;адресс сервера
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
$SendPort = 65432 ;Указываем порт к которому будем подключаться
$RecvPort = 65433 ;Указываем порт к которому будем подключаться
$tTime = TimerInit()
Do
    $socket = TCPConnect($nIP, $SendPort);Указыываем ОС создать сокет, подключенный к указанному адресу
Until $socket <> -1

TCPSend($socket, @ComputerName & ' онлайн (в сети уже ' & TimerDiff($tTime) / 1000 & ')');Отправляем данные на сервер
TCPCloseSocket($socket)


$MainSocket = TCPListen($nIP, $RecvPort,  100 )
If $MainSocket = -1 Then Exit
ConsoleWrite("TCPListen - >" & $MainSocket & @CRLF)


While 1

    $ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета

        While 1
            $result = TCPRecv($ConnectedSocket, 2048)
            If $result <> '' Then ;если данные есть,то принимаем первые 2048

                If $result = 'ping' Then
                    MsgBox(16, '', 'ping : yes')
                    $socket = TCPConnect(SocketToIP($ConnectedSocket), $SendPort);Указыываем ОС создать сокет, подключенный к указанному адресу
                    SocketToIP($ConnectedSocket)
                    TCPSend($socket, "time " & @MDAY & "-" & @MON & "-" & @YEAR & "  /  " & @HOUR & ":" & @MIN & ":" & @SEC)
                    TCPCloseSocket($socket)

                EndIf

                Sleep(25)
            Else
                ExitLoop
            EndIf
        WEnd

    EndIf

WEnd





Func SendingData($MainSocket_A0, $data)
    $socket = TCPConnect(SocketToIP($MainSocket_A0), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
    Return TCPSend($socket, $data);Отправляем данные на сервер
    TCPCloseSocket($socket)
EndFunc   ;==>SendingData

Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP

Renz [?]
PS: Работает на разных копмах, если клиент и сервер на одном то не работает
Всё прекрасно работает ;)
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
А можно ли так сделать,чтобы использовался только один порт....?
 

Renz

Осваивающий
Сообщения
63
Репутация
36
qsort сказал(а):
[quote author=Dream-52]
А можно ли так сделать,чтобы использовался только один порт....?
А с о одним портом?
А это как?;) Чтоб и IP один и порт один?
IP - уникально идентифицирует компьютер.
Порт - уникально идентифицирует программу.
Комбинация IP + порт называется сокетом.
Разумеется, две программы (клиент и сервер) не могут использовать один и тот же сокет.
[/quote]
вопрос был не с одним сокетом а с одним портом ;)
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Renz [?]
вопрос был не с одним сокетом а с одним портом
Вам собственно qsort уже ответил ;)
Однако... Код "причёсывать" не стал, просто пример.
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>


$SRIP = @IPAddress1
$CLIP = "127.0.0.1"
$Port = 65433

;~ $SendPort = 65433
;~ $Port = 65432
Global $aSockets, $i, $rep, $MainSocket, $socket, $Result, $IP, $port, $ipBotOld, $aSockets[1]


#Region GUI Server

$GUI = GUICreate("Server", 970, 618, (@DesktopWidth-970)/2, (@DesktopHeight-618)/2)
$GenGUI = GUICtrlCreateList("", 0, 0, 820, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$BotsGUI = GUICtrlCreateList("", 820, 0, 149, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$InputString = GUICtrlCreateEdit("", 0, 568, 969, 49, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL))

GUICtrlSetFont($GenGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($BotsGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($InputString, 12, 200, 1, "Georgia")

GUISetState(@SW_SHOW)

#EndRegion GUI Server

TCPStartup()

$MainSocket = TCPListen($SRIP, $Port, 1000) ;Создаем слушающий сокет, по указанному адресу
If $MainSocket = -1 Then Exit

While 1

    $MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    $Result = ReceiveData($MainSocket_A) ;проверяем входящее соединение на наличие пакета
    If $Result Then
		
        GUICtrlSetData($BotsGUI, $CLIP)
        GUICtrlSetData($GenGUI, ' ' & $CLIP & ' >> ' & $Result)
        TCPCloseSocket($MainSocket_A);Закрываем сокет

    EndIf


    $ipBot = GUICtrlRead($BotsGUI)
    If $ipBot = "" Or $ipBot = $ipBotOld Then
	Else
        GUICtrlSetData($GenGUI, 'запрос данных...')
        MsgBox(16, '', $ipBot & ':' & $Port)
        $socket = TCPConnect($CLIP, $Port)
        TCPSend($socket, 'ping')
        TCPCloseSocket($socket)
        $ipBotOld = $ipBot

    EndIf

WEnd


TCPShutdown()


Func ReceiveData($ConnectedSocket)

    If $ConnectedSocket <> -1 Then
        $aSockets[0] = UBound($aSockets)
        ReDim $aSockets[UBound($aSockets) + 1]
        $aSockets[UBound($aSockets) - 1] = $ConnectedSocket
    EndIf

    For $i = 1 To $aSockets[0]
        Return TCPRecv($aSockets[$i], 256, 0)
        If @error Then
            TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

            For $ii = $i To $aSockets[0] - 1
                $aSockets[$ii] = $aSockets[$ii + 1]
            Next
            $aSockets[0] -= 1
            ReDim $aSockets[UBound($aSockets) + 1]

            ContinueLoop 2
        EndIf
    Next

EndFunc   ;==>ReceiveData
Код:
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_UseUpx=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup();Инициировать использование службы TCP

$SRIP = @IPAddress1
$CLIP = "127.0.0.1"
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
$Port = 65433 ;Указываем порт к которому будем подключаться
$tTime = TimerInit()
Do
    $socket = TCPConnect($SRIP, $Port);Указыываем ОС создать сокет, подключенный к указанному адресу
Until $socket <> -1

TCPSend($socket, @ComputerName & ' онлайн (в сети уже ' & TimerDiff($tTime) / 1000 & ')');Отправляем данные на сервер
TCPCloseSocket($socket)


$MainSocket = TCPListen($CLIP, $Port,  100 )
If $MainSocket = -1 Then Exit


While 1

    $ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета

        While 1
            $result = TCPRecv($ConnectedSocket, 2048)
            If $result <> '' Then ;если данные есть,то принимаем первые 2048

                If $result = 'ping' Then
                    MsgBox(16, '', 'ping : yes')
                    $socket = TCPConnect(@IPAddress1, $Port);Указыываем ОС создать сокет, подключенный к указанному адресу
                    TCPSend($socket, "time " & @MDAY & "-" & @MON & "-" & @YEAR & "  /  " & @HOUR & ":" & @MIN & ":" & @SEC)
                    TCPCloseSocket($socket)
                EndIf
				
            Else
                ExitLoop
            EndIf
        WEnd

    EndIf

WEnd
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
:laugh: Доброе утро,ребята ! Все такие не получилось решить главную проблему... - сервер нивкакую не хочет принимать ответ от клиента. И я не могу понять почему.... пожалуйста подскажите,в чем может быть дело.А я буду пробывать дальше :whistle:

Клиент :

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#AutoIt3Wrapper_UseUpx=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup();Инициировать использование службы TCP
$nIP = '192.168.0.1' ;адресс сервера
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
$port = 59888 ;Указываем порт к которому будем подключаться
$tTime = TimerInit()

Do
$socket = TCPConnect('192.168.0.1', $port);Указыываем ОС создать сокет, подключенный к указанному адресу
Until $socket <> -1

TCPSend($socket, @ComputerName & ' онлайн (в сети уже ' & TimerDiff($tTime) / 1000 & ')');Отправляем данные на сервер
Sleep(100)
TCPCloseSocket($socket)
Sleep(100)
Global $MainSocket, $nIPmy = '192.168.0.6'
$MainSocket = TCPListen($nIPmy, $port, 1000) ; создаем прослушивающий СОКЕТ


While 1

$ConnectedSocket = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
If $ConnectedSocket <> -1 Then ;проверяем входящее соединение на наличие пакета

While 1
$result = TCPRecv($ConnectedSocket, 2048)
If $result <> '' Then
ConsoleWrite(@CRLF & '$result - ' & $result)
If $result = 'ping' Then
$socket = TCPConnect(SocketToIP($ConnectedSocket), $port);Указыываем ОС создать сокет, подключенный к указанному адресу
ConsoleWrite(@CRLF & 'SocketToIP($ConnectedSocket) - ' & SocketToIP($ConnectedSocket))
$TCPSend = TCPSend($socket,"time " & @MDAY & "-" & @MON & "-" & @YEAR & " / " & @HOUR & ":" & @MIN & ":" & @SEC) ; ВОТ ЗДЕСЬ ДАННЫЕ ПЕРЕДАЮТСЯ,НО НЕ ПОЛУЧАЕТ СЕРВЕР.
ConsoleWrite(@CRLF & '$TCPSend - ' & $TCPSend)
Sleep(25)
TCPCloseSocket($socket)
EndIf
Else
ExitLoop
EndIf
WEnd

EndIf

WEnd


Func SocketToIP($SHOCKET)
Local $sockaddr, $aRet
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")

$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
If Not @error And $aRet[0] = 0 Then
$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aRet = $aRet[0]
Else
$aRet = 0
EndIf
$sockaddr = 0

Return $aRet
EndFunc ;==>SocketToIP

TCPShutdown();Завершить использование службы TCP

Сервер :


#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>

$IP = '192.168.0.1'
$port = 59888
Global $aSockets, $i, $rep, $MainSocket, $socket, $result, $IP, $port, $ipBotOld

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)


$GUI = GUICreate("Server", 970, 618, 108, 292)
$GenGUI = GUICtrlCreateList("", 0, 0, 820, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$BotsGUI = GUICtrlCreateList("", 820, 0, 149, 567, BitOR($LBS_SORT, $LBS_STANDARD, $WS_VSCROLL, $WS_BORDER), BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
$InputString = GUICtrlCreateEdit("", 0, 568, 969, 49, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL))

GUICtrlSetFont($GenGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($BotsGUI, 12, 200, 1, "Georgia")
GUICtrlSetFont($InputString, 12, 200, 1, "Georgia")

GUISetState(@SW_SHOW)

TCPStartup()

$MainSocket = TCPListen($IP, $port, 1000) ;Создаем слушающий сокет, по указанному адресу

Dim $aSockets[1] = [0]
$IpSelect = 0

While 1
Sleep(1000)
$MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
ConsoleWrite(@CRLF & '$MainSocket_A = ' & $MainSocket_A)
If $MainSocket_A > 1 Then

ConsoleWrite(@CRLF & '$MainSocket_A (2)= ' & $MainSocket_A)
$result = ReceiveData($MainSocket_A) ;проверяем входящее соединение на наличие пакета
ConsoleWrite(@CRLF & '$result = ' & $result)
If $result <> '' Or $result <> '0' Then
$SocketToIp = SocketToIP($MainSocket_A)
GUICtrlSetData($BotsGUI, $SocketToIp)
GUICtrlSetData($GenGUI, ' ' & $SocketToIp & ' >> ' & $result)
Sleep(10)
EndIf
TCPCloseSocket($MainSocket_A);Закрываем сокет
EndIf


$ReadIp = GUICtrlRead($BotsGUI)
If $ReadIp <> 0 Or $ReadIp <> '' Then

If $ReadIp <> $IpSelect Then

ConsoleWrite(@CRLF & '$ReadIp <> $IpSelect = ' & $ReadIp & ' ' & $IpSelect)
ConsoleWrite(@CRLF & '$ReadIp = ' & $ReadIp)
$Socket__ = TCPConnect($ReadIp, $port)
If $Socket__ <> -1 Then
ConsoleWrite(@CRLF & '$Socket__ = ' & $Socket__)
$sendPacket = TCPSend($Socket__, 'ping')

If $sendPacket <> 0 Then
ConsoleWrite(@CRLF & '$sendPacket = ' & $sendPacket)
EndIf

EndIf
TCPCloseSocket($Socket__)
$IpSelect = $ReadIp

EndIf
EndIf

WEnd

Func ReceiveData($ConnectedSocket)

If $ConnectedSocket <> -1 Then
$aSockets[0] += 1
ReDim $aSockets[$aSockets[0] + 1]
$aSockets[$aSockets[0]] = $ConnectedSocket
EndIf

For $i = 1 To $aSockets[0]
Return TCPRecv($aSockets[$i], 256, 0)
If @error Then
TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

For $j = $i To $aSockets[0] - 1
$aSockets[$j] = $aSockets[$j + 1]
Next
$aSockets[0] -= 1
ReDim $aSockets[$aSockets[0] + 1]

ContinueLoop 2
EndIf
Sleep(5)
Next

EndFunc ;==>ReceiveData

Func SocketToIP($SHOCKET)
Local $sockaddr, $aRet
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")

$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
If Not @error And $aRet[0] = 0 Then
$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aRet = $aRet[0]
Else
$aRet = 0
EndIf
$sockaddr = 0

Return $aRet
EndFunc ;==>SocketToIP



TCPShutdown()



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

:laugh: нашел в чем проблема,просто никогда бы не подумал,что именно в этом ))


Код:
Func ReceiveData($ConnectedSocket)

	If $ConnectedSocket <> -1 Then
		$aSockets[0] += 1
		ReDim $aSockets[$aSockets[0] + 1]
		$aSockets[$aSockets[0]] = $ConnectedSocket
	EndIf

	For $i = 1 To $aSockets[0]
		Return TCPRecv($aSockets[$i], 256, 0)
		If @error Then
			TCPCloseSocket($aSockets[$i]) ; Закрываем нужный сокет

			For $j = $i To $aSockets[0] - 1
				$aSockets[$j] = $aSockets[$j + 1]
			Next
			$aSockets[0] -= 1
			ReDim $aSockets[$aSockets[0] + 1]

			ContinueLoop 2
		EndIf
		Sleep(5)
	Next

EndFunc   ;==>ReceiveData



Вот в этой ф-ции. Дело в том,что мне нужно,чтобы к серверу могли приконектится неограниченное количество клиентов
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
Оказываетс проблема была в .....том,что не было пауз (sleep).
Код:
.....

	$MainSocket_A = TCPAccept($MainSocket) ;Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
	Sleep(100)
	If $MainSocket_A <> -1 Then
		$result = TCPRecv($MainSocket_A, 256) ;проверяем входящее соединение на наличие пакета
		Sleep(100)
		If $result <> '' Or $result <> '0' Then
			Sleep(100)


....



Не знаю почему...но как вижу,это сильно (!) влияет на работу TCP - цыкла.
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
Решение в применении Opt("TCPTimeout", '') - я прав ? :whistle:


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

qsort сказал(а):
Здесь-то, наверно, все понятно. Пакеты же, передаются не со скоростью света ;)
Хотя, конечно, извини, я не в курсе какая у тебя скорость Интернета, может, настолько крутая, что мне со своими 50 Мбит/с и помолчать бы, стоило...
Решение в применении Opt("TCPTimeout", '')
ЗЫ Да, возможно, и в этом дело. Я тоже, помнится, его как-то устанавливал.

Вроде бы помогло :whistle:

Кстати да,у меня связь между компами не 50...а 100 мб 8)


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

qsort сказал(а):
Здесь-то, наверно, все понятно. Пакеты же, передаются не со скоростью света ;)
Хотя, конечно, извини, я не в курсе какая у тебя скорость Интернета, может, настолько крутая, что мне со своими 50 Мбит/с и помолчать бы, стоило...
Решение в применении Opt("TCPTimeout", '')
ЗЫ Да, возможно, и в этом дело. Я тоже, помнится, его как-то устанавливал.
AutoItSetOption("TCPTimeout", 10)
Это в первом попавшемся под руку файле. Наверно, зачем-то я так делал когда-то!;)
Как это ? ...если там минимум - 100 ? вернее то ,что стоит по умолчанию......


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

qsort сказал(а):
Здесь-то, наверно, все понятно. Пакеты же, передаются не со скоростью света ;)
Хотя, конечно, извини, я не в курсе какая у тебя скорость Интернета, может, настолько крутая, что мне со своими 50 Мбит/с и помолчать бы, стоило...
Решение в применении Opt("TCPTimeout", '')
ЗЫ Да, возможно, и в этом дело. Я тоже, помнится, его как-то устанавливал.
AutoItSetOption("TCPTimeout", 10)
Это в первом попавшемся под руку файле. Наверно, зачем-то я так делал когда-то!;)
ЗЗЫ Сейчас уже не вспомню почему именно 10, но опция такая стоит в исходнике, программа уже давно отлажена и давно уверенно работает.
...если там минимум - 100 ?
ЗЗЗЫ Значит установка опции повлиять не могла.
Дело только в Sleep(), который, надо полагать, зависит от скорости соединения. В любом случае, мгновенно не происходит ничего.
Например, (сейчас просто исходник соединения с модемом открыт), чтобы получить ответ от модема на ATZ достаточно 50мс, а чтобы получить "длинный" ответ на ATI (конфигурация модема, там целая куча строк), требуется уже 300мс. Вот и приходится выставлять Sleep(300).

Да,таки прав....
По-моему дело действительно в паузе.Правда в моем данном случае,не совсем понимаю как это рабоатет (ведь все в цыкле всеравно)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Dream-52
Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, Модератор раздела.
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
А вот файл передать пока не получается...
 

svigelf

Знающий
Сообщения
61
Репутация
17
попробуй такой способ(он конечно не идеален, сам не проверял, но теоретически работает)
если чтото не так, то поправьте :-[
Код:
;(Клиент)

$data = InputBox("Отправить", "Введите данные для отправки на сервер :", "") ;отправить на сервер строку
$binary = StringToBinary($data) ;переводим данные в бинарный код(чтобы его подсчитать)
$BinaryLen1 = BinaryLen($binary) ;подсчет кол-ва байтов в строке, которую мы отправляем
$binary1 = StringToBinary($BinaryLen1 & ":") ;переводим в бинарный код "число байтов" для отправки на сервер + символ ":"
$BinaryLen2 = BinaryLen($binary1) ;подсчет байтов, котоых получили выше ($binary1)
$number = $BinaryLen1 + $BinaryLen2 ;складываем количество байтов
;MsgBox(64, "Test", "Количество байтов в данных : " & $BinaryLen1, 10)
;MsgBox(64, "Test", "Количество байтов в подсчете(байтов) : " & $BinaryLen2, 10)
;MsgBox(64, "Test", "Количество байтов в отправке на сервер : " & $number, 10)
;на сервер отправляем так:
TCPSend ("сокет", $number & ":" & $data)
;тоесть выходит такая штука: "колво байтов в переданной строке:сама строка"

;(Сервер)

$data = TCPRecv( "Сокет", "Колво символов максимальное" )
Do
	$binary = StringToBinary($data) ;переводим строку в байты,чтобы их считать
	StringSplit($data, ":") ;разделяем строку "$data", чтобы можно было отделить саму строку от числа байтов(в начале строки, которую получил сервер)
	$BinaryLen = BinaryLen($binary) ;считаем кол-во байтов в строке,которую получил сервер
Until $data[1] = $BinaryLen;проверяем равенство кол-ва байтов в строке "$data" c "$data[1]"(количество байтов, посчитанное в клиенте)

;продолжаем работать с переменной data[2] - с нужной нам строчкой
 
Автор
D

Dream-52

...
Сообщения
82
Репутация
1
а вот как файл передать то ?
 
Верх