Что нового

[Сеть, интернет] Как передать файл по локальной сети?

JusteG

Новичок
Сообщения
7
Репутация
0
Уважаемые гуру, как посредствам автоита передать файл по локальной сети?
т.е. в общих чертах скрипт должен выглядеть так: есть сервер, и клиент, клиент отправляет указанный файл скрверу, а сервер его принимает и сохраняет в указанную папку.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
что есть сервер и что есть клиент?
просто две машины в локальной сети доступные по самбе?
или там другой механизм доступа клиента к серверу?
зачем скупиться на слова? не платные же ;)
 
Автор
J

JusteG

Новичок
Сообщения
7
Репутация
0
Есть 2 компьютера соединенных между собой локальной сетью. Есть приложение написанное на автоите которое умеет открывать порт на прослушку, оно и является сервером. Есть приложение которое умеет отправлять сообщения серверу на открытый порт, при этом сервер имея обработчик команд исполняет действия отправляемые клиентом. Вот мне бы научить клиент отправлять файлы, а сервер их принимать.
Да, кстати, недавно объеденил сервер и клиент в одном приложении в общем вот:

Код:
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)

#NoTrayIcon
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <GuiEdit.au3>
#include <Array.au3>
#include <Date.au3>

Opt("TrayMenuMode",1)
TraySetState(1)

Global $Server_IP = InputBox("Chat Client", "Gimme The Server IP Address", "192.168.1.6", "", 300, 200)
Global $Server_Port = 33300
Global $Lisening_IP = @IPAddress1, $Lisening_port = 33300, $Connected_Socket[101], $Number_Of_Connections = 1
Global $Active_Connection, $Data_Vith_Server = "", $Data_Vidouth_Server = ""

For $i = 1 To 100
	$Connected_Socket[$i] = -1
Next

TCPStartup()

$Lisening_Socket = TCPListen($Lisening_IP, $Lisening_port, 100)
If $Lisening_Socket = -1 Then Exit

$Socket_To_Send = TCPConnect($Server_IP, $Server_Port)
If $Socket_To_Send = -1 Then Exit

$Client_Window = GUICreate("TCP Control Tool", 600, 250, -1, -1, BitOR($WS_POPUP, $WS_SYSMENU, $WS_CAPTION))
$Client_Edit = GUICtrlCreateEdit("", 10, 40, 580, 200, BitOR ($ES_READONLY, $WS_VSCROLL, $ES_AUTOVSCROLL))
$Client_Input = GUICtrlCreateInput("", 10, 10, 250, 20)
$Client_Buttom = GUICtrlCreateButton("Send", 260, 10, 80, 20, $BS_DEFPUSHBUTTON)
$Client_Check = GUICtrlCreateCheckbox ("Server dialog", 350, 10, 100, 20)

GUISetState()

While 1
	$Msg = GUIGetMsg()
	
	If $Msg = $GUI_EVENT_CLOSE Then ExitLoop
	If $Msg = $Client_Check Then
		If GUICtrlRead ($Client_Check) = 1 Then GUICtrlSetData($Client_Edit, $Data_Vith_Server)
		If GUICtrlRead ($Client_Check) = 4 Then GUICtrlSetData($Client_Edit, $Data_Vidouth_Server)
	EndIf
	#Region Send To Server
	If $Msg = $Client_Buttom Then Set_To_Edit(GUICtrlRead ($Client_Input), 1)
	#EndRegion Send To Server
	
	#Region Resive From Client
	
		$Connected_Socket[$Number_Of_Connections] = TCPAccept($Lisening_Socket)
		If $Connected_Socket[$Number_Of_Connections] >= 0 Then
			Set_To_Edit ("Connected client from IP " & Socket2IP($Connected_Socket[$Number_Of_Connections]), 5)
			$Number_Of_Connections += 1
		EndIf
		
		For $i = 1 To $Number_Of_Connections - 1
			$Message_From_Client = TCPRecv($Connected_Socket[$i], 512)
			If $Message_From_Client <> "" Then
				$Connected_Socket[0] = $i
				Set_To_Edit ($Message_From_Client, 4)
				Switch $Message_From_Client
					Case "~Terminate Connection~"
						Set_To_Edit ("Executing command " & $Message_From_Client, 3)
						TCPCloseSocket($Connected_Socket[$Connected_Socket[0]])
						$Connected_Socket[$Connected_Socket[0]] = -1
						_ArraySort ($Connected_Socket, 1, 1)
						$Number_Of_Connections -= 1
						Set_To_Edit ("Command executing susesfully " & $Message_From_Client, 5)
					Case "~Hide Tray Icon~"
						Set_To_Edit ("Executing command " & $Message_From_Client, 3)
						TraySetState(2)
						Set_To_Edit ("Command executing susesfully " & $Message_From_Client, 5)
					Case "~Show Tray Icon~"
						Set_To_Edit ("Executing command " & $Message_From_Client, 3)
						TraySetState(1)
						Set_To_Edit ("Command executing susesfully " & $Message_From_Client, 5)
					Case "~Attention Tray Icon On~"
						Set_To_Edit ("Executing command " & $Message_From_Client, 3)
						TraySetState(4)
						Set_To_Edit ("Command executing susesfully " & $Message_From_Client, 5)
					Case "~Attention Tray Icon Off~"
						Set_To_Edit ("Executing command " & $Message_From_Client, 3)
						TraySetState(8)
						Set_To_Edit ("Command executing susesfully " & $Message_From_Client, 5)
					Case Else
						Set_To_Edit ("Server is ressive message " & $Message_From_Client, 3)
				EndSwitch
			EndIf
		Next
	#EndRegion Resive From Client
	
	#Region Resive Ansver From Server
	$Message_From_Server = TCPRecv($Socket_To_Send, 512)
	$Err = @error
	If $Err <> 0 Then ExitLoop
	If $Err = 0 And $Message_From_Server <> "" Then Set_To_Edit($Message_From_Server, 2)
	#EndRegion Resive Ansver From Server
WEnd

Func OnAutoItExit()
	TCPSend ($Socket_To_Send, "~Terminate Connection~")
	TCPCloseSocket($Lisening_Socket)
	TCPCloseSocket($Connected_Socket[1])
	TCPCloseSocket($Socket_To_Send)
	TCPShutdown()
EndFunc

Func Set_To_Edit ($Message, $Config)
	Select
		Case $Config = 1
			$Message_To_Server = TCPSend($Socket_To_Send, $Message)
			GUICtrlSetData($Client_Input, "")
			$Data_Vidouth_Server = _NowCalc () & " || " & $Server_IP & @TAB  & "<--" & @TAB  & $Message & @CRLF & $Data_Vidouth_Server
			$Data_Vith_Server =  _NowCalc () & " || " & $Server_IP & @TAB  & "<--" & @TAB  & $Message & @CRLF & $Data_Vith_Server
		Case $Config = 2
			$Data_Vidouth_Server = _NowCalc () & " || " & $Server_IP & @TAB  & "-->" & @TAB  & $Message & @CRLF & $Data_Vidouth_Server
			$Data_Vith_Server = _NowCalc () & " || " & $Server_IP & @TAB  & "-->" & @TAB  & $Message & @CRLF & $Data_Vith_Server
		Case $Config = 3
			TCPSend ($Connected_Socket[$Connected_Socket[0]], $Message)
			$Data_Vith_Server = _NowCalc () & " || " & Socket2IP($Connected_Socket[$Connected_Socket[0]]) & @TAB  & "<--" & @TAB  & $Message & @CRLF & $Data_Vith_Server
		Case $Config = 4
			$Data_Vith_Server = _NowCalc () & " || " & Socket2IP($Connected_Socket[$Connected_Socket[0]]) & @TAB  & "-->" & @TAB  & $Message & @CRLF & $Data_Vith_Server
		Case $Config = 5
			$Data_Vith_Server = _NowCalc () & " || SERVER" & @TAB & ">-<" & @TAB  & $Message & @CRLF & $Data_Vith_Server
	EndSelect
	ConsoleWrite ($Data_Vidouth_Server & @CRLF & @CRLF)
	If GUICtrlRead ($Client_Check) = 1 Then GUICtrlSetData($Client_Edit, $Data_Vith_Server)
	If GUICtrlRead ($Client_Check) = 4 Then GUICtrlSetData($Client_Edit, $Data_Vidouth_Server)
EndFunc

Func Socket2IP($Socket)
	Local $sockaddr, $aRet
	$sockaddr = DllStructCreate("short;ushort;uint;char[8]")
	$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $Socket, _
			"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


При запуске указать свой айпи, пока еще гуй для клиента не нарисовал...
Да, вот еще, как зная айпи узнать имя компьютера?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Тихо сам с собою, я веду беседу ;D ©
Я не понял, проблема решилась?
[?]
Да, кстати, недавно объеденил сервер и клиент
зачем?
для решения конкретно твоей задачи, кстати которая была далеко не очевидно из сообщения в шапке ;), необходимо чтобы один скрипт был запущен на сервере, другой на клиентской машине. только я не понимаю зачем все эти сложности, почему бы просто не расшарить папку и кидать туда файлы?
а вообще, твой скрипт я не особо смотрел, но вроде основные вещи написаны. только надо раскидать на клиентскую и серверную части.

Да, вот еще, как зная айпи узнать имя компьютера?
Код:
#include <iNet.au3>
$ip = _GetIp()
MsgBox(64, 'Computer name', 'NetBIOS for ' & $ip ' is ' & _TCPIPToName($ip))

еще, могу посоветовать принимать данные в бинарном виде. выставляется флагом flag = 1 для TCPRecv()
 
Автор
J

JusteG

Новичок
Сообщения
7
Репутация
0
Уважаемые знатоки! Вопрос все еще открыт! Как передать файл по локальной сети? Код клиента/сервера звучал выше.

По поводу обединения в одном приложении - не лишенно смысла в силу специфичной задачи стоящей перед программой, в силу той - же специфичности, невозможно решить вопрос простым расшариванием ресурса и копированием из него.
 
Автор
J

JusteG

Новичок
Сообщения
7
Репутация
0
Чё знатоки на форуме перевелись что-ли???
Никто прям ничего не знает??? Давайте подумаем, у кого какие соображения есть?
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1 554
Репутация
328
Так. Я сейчас буду ругаться :Rulz:
CreatoR сказал(а):
Обычно поднимают тему минимум через пару суток, а не через пару часов.
Если вам не отвечают, значит ответ на вопрос сложен, и не может быть решен в короткое время!
Во вторых. НЕ нужно раскрашивать сообщения постоянно.
В третьих. Взгляните на эту тему. В основном нужно вам смотреть страницу 3. Там подробно написано.
В четвертых. Я не буду выписывать предупреждение. Но имейте ввиду - нарушение правил ни к чему хорошему не приведут

OffTopic:
P.S. Нужно немного обновить правила...
 

SyDr

Сидра
Сообщения
651
Репутация
158
Сервер:
Отсылаешь клиенту некоторое значение, означающее, что сейчас будет передан файл.
Передаёшь размер имени файла.
Передаёшь имя файла.
Передаёшь размер файла.
Передаёшь сам файл.

Клиент:
Получаешь значение и определяешь, что сейчас будет. Если файл:
Получаешь размер имени файла.
Получаешь имя файла.
Получаешь размер файла.
Получаешь файл.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
SyDr
мне кажется что в твоем посте надо заменить сервер на клиент и наоборот ;D, т.к ТС хотел передать файл серверу, а там разложить его в полочку.


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

JusteG
Мне не хочется лопатить твой код, т.к. он громоздкий. мне чесгря лень. ты только вот что скажи, что там не работает? в чем затык? что у тебя не получается передать?
при беглом взгяде, порт вроде открывается, прослушивается, какие-то "синтаксически неправильные" слова на аглицком отправляются.
если не удается отправлять файл, то я тебе уже говорил, принимай данные в бинарном виде. для этого
клиент должен начать считывать файл скажем по 100 кб в бинарном виде. механизм
Код:
$sFile = 'path to the file'
$hRead = FileOpen($sFile, 16); binary read mode
While 1
   $xData = FileRead($hOpen, 100*1024); read 100 kb of data
   If @error = -1 Then ExitLoop
   ;Do something. Например передавай серверу ;)
WEnd
FileClose($hOpen)

сервер должен начать принимать данные с прослушиваемого порта и знать, что передаются сырые данные, и начать например записывать их в файл, а затем с этим файлом что-либо делать. механизм
Код:
$sFile = 'path to the file'
$hWrite = FileOpen($sFile, 16+2); Create file to write binary data
;... some code
$xData = TCPRecv($socket, 100*1024, 1); Read 100 kb of data
FileWrite($hWrite, $xData)
;some code

детали сможешь реализовать сам? :smile:
 

TheBloodTear

Знающий
Сообщения
36
Репутация
9
Хотелось бы поднять немного тему ;)..
Открывать файл в бинарном типе - это конечно здорово, но вот только есть пару вопросов и мыслей :smile::
1) Какова максимальная величина пакета для передачи?
- просто как я понимаю, можно обойти размерность файлов, разбивая данные на куски, и поэтому интересен потолок пакетов.
-ведь есть шанс того что пакеты вообще потеряются, а ведь чем их больше тем выше шанс :smile:..

2) Как прочесть "эти" бинарные данные из большого файла?..

Вот у меня есть маленький скрипт, он не использует TCP но он копирует файл используя "этот" бинарный способ:

Код:
$FileOpenDialog = FileOpenDialog ("Выберите файл", @ScriptDir, "Все файлы (*.*)")
$Corp = StringSplit($FileOpenDialog, ".")
$FileSaveDialog = FileSaveDialog ("Выберите папку назначения", @ScriptDir, "Все файлы (*." & $Corp[$Corp[0]] & ")")
$FileOpen = FileOpen ($FileOpenDialog, 16)
$FileRead = FileRead($FileOpen)
FileClose($FileOpen)

$FileSize = BinaryLen($FileRead)
$FileSizePerc = Round($FileSize/100000 + 1)
$Perc = Round(($FileSizePerc/$FileSize)*100)

ProgressOn ("Копирование файла", "Идет копирование файла:" & @CRLF & $FileOpenDialog & @CRLF & "в конечную точку:" & _
			@CRLF & $FileSaveDialog, "Скопировано 0%")
If $FileSize < 100000 Then
	ProgressSet (25, "Скопировано 25%")
	$rFileOpen = FileOpen($FileSaveDialog & "." & $Corp[$Corp[0]], 16 + 2)
	ProgressSet (25, "Скопировано 50%")
	$rFileWrite = FileWrite($rFileOpen, $FileRead)
	ProgressSet (25, "Скопировано 75%")
	FileClose($rFileOpen)
	ProgressSet (25, "Скопировано 100%")
	ProgressOff ()
Else
	$rFileOpen = FileOpen($FileSaveDialog & "." & $Corp[$Corp[0]], 16 + 1)
	$r = 1
	For $i = 1 To $FileSizePerc
		$buff = BinaryMid($FileRead, $r, 100000)
		$rFileWrite = FileWrite($rFileOpen, $buff)
		$r += 100000
		ProgressSet ($Perc, "Скопировано " & $Perc & "%")
		$Perc += $Perc
	Next
	FileClose($rFileOpen)
	ProgressSet (100, "Скопировано 100%")
	ProgressOff ()
EndIf


С его помощью я легко передаю файлы размером ~1 Мб (другие не пробывал), но когда я попробывал скопировать ISO-образ (700 Мб) мой компьютер совсем одурел ;D.. Использовалась вся оперативная память..И спас только Reboot ;D..

Если есть у кого, какие-нибудь мысли или советы по поводу, того как это обойти "это" буду рад ;)..
 
Верх