Modify

Opened 6 years ago

Closed 6 years ago

#2669 closed Bug (No Bug)

TCP Send and TCP Receive (Example 2)

Reported by: AoRaToS Owned by: FireFox
Milestone: Component: Documentation
Version: 3.3.10.2 Severity: None
Keywords: TCPSend, TCPRecv Cc:

Description (last modified by FireFox)

Hello,

There is an issue with the examples in these 2 functions. The server is also the one sending the file so there is a mistake. TCP Receive is the one that should be started first and wait for a connection. Then you run TCP Send and choose a file to send. Once TCP Receive sees the connection it asks where to save the file.
The functions should be updated as below i believe. Tested and working. I have also updated the comments at the top to be correct.

TCP Send:

; I am the client, start me after the server! (First start example 2 of the TCPRecv function).

#include <MsgBoxConstants.au3>
#include <FileConstants.au3>

Example()

Func Example()
	; Assign a Local variable the path of a file chosen through a dialog box.
	Local $sFilePath = FileOpenDialog("Select a file to send", @MyDocumentsDir, "All types (*.*)", BitOR($FD_FILEMUSTEXIST, $FD_PATHMUSTEXIST))
	Local $iError = 0

	; Note: Choose a file bigger than 4 kiB otherwise the first example is enough.

	; If an error occurred display the error code and return False.
	If @error Then
		$iError = @error
		MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONEXCLAMATION), "", "Server:" & @CRLF & "Invalid file chosen, Error code: " & $iError)
		Return False
	EndIf

	TCPStartup() ; Start the TCP service.

	; Register OnAutoItExit to be called when the script is closed.
	OnAutoItExitRegister("OnAutoItExit")

	; Assign Local variables the loopback IP Address and the Port.
	Local $sIPAddress = "127.0.0.1" ; This IP Address only works for testing on your own computer.
	Local $iPort = 65432 ; Port used for the connection.

	; Assign a Local variable the socket and connect to a listening socket with the IP Address and Port specified.
	Local $iSocket = TCPConnect($sIPAddress, $iPort)
	Local $iError = 0

	; If an error occurred display the error code and return False.
	If @error Then
		; The server is probably offline/port is not opened on the server.
		$iError = @error
		MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Client:" & @CRLF & "Could not connect, Error code: " & $iError)
		Return False
	EndIf

	; Assign a Local variable the size of the file previously chosen.
	Local $iFileSize = FileGetSize($sFilePath)

	; Assign a Local variable the handle of the file opened in binary mode.
	Local $hFile = FileOpen($sFilePath, $FO_BINARY)

	; Assign a Local variable the offset of the file being read.
	Local $iOffset = 0

	; Assign a Local variable the number representing 4 KiB.
	Local Const $i4KiB = 4096

	; Note: The file is send by parts of 4 KiB.

	; Send the binary data of the file to the server.
	Do
		; Set the file position to the current offset.
		FileSetPos($hFile, $iOffset, $FILE_BEGIN)

		; The file is read from the position set to 4 KiB and directly wrapped into the TCPSend function.
		TCPSend($iSocket, FileRead($hFile, $i4KiB))

		; If an error occurred display the error code and return False.
		If @error Then
			$iError = @error
			MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Server:" & @CRLF & "Could not send the data, Error code: " & $iError)

			; Close the socket.
			TCPCloseSocket($iSocket)
			Return False
		EndIf

		; Increment the offset of 4 KiB to send the next 4 KiB data.
		$iOffset += $i4KiB
	Until $iOffset >= $iFileSize

	; Close the file handle.
	FileClose($hFile)

	; Tell the client the file is fully sent with a code.
	TCPSend($iSocket, @CRLF & "{EOF}")

	; Display the successful message.
	MsgBox($MB_SYSTEMMODAL, "", "Server:" & @CRLF & "File sent.")

	; Close the socket.
	TCPCloseSocket($iSocket)
EndFunc   ;==>Example

Func OnAutoItExit()
	TCPShutdown() ; Close the TCP service.
EndFunc   ;==>OnAutoItExit

TCP Receive:

; I am the server, start me first! (The start example 2 of the TCPSend function).

#include <MsgBoxConstants.au3>
#include <FileConstants.au3>

Example()

Func Example()
	TCPStartup() ; Start the TCP service.

	; Register OnAutoItExit to be called when the script is closed.
	OnAutoItExitRegister("OnAutoItExit")

	; Assign Local variables the loopback IP Address and the Port.
	Local $sIPAddress = "127.0.0.1" ; This IP Address only works for testing on your own computer.
	Local $iPort = 65432 ; Port used for the connection.

; Assign a Local variable the socket and bind to the IP Address and Port specified with a maximum of 100 pending connexions.
	Local $iListenSocket = TCPListen($sIPAddress, $iPort, 100)

	; If an error occurred display the error code and return False.
	If @error Then
		; Someone is probably already listening on this IP Address and Port (script already running?).
		$iError = @error
		MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Server:" & @CRLF & "Could not listen, Error code: " & $iError)
		Return False
	EndIf

	; Assign a Local variable to be used by the Client socket.
	Local $iSocket = 0

	Do ; Wait for someone to connect (Unlimited).
		; Accept incomming connexions if present (Socket to close when finished; one socket per client).
		$iSocket = TCPAccept($iListenSocket)

		; If an error occurred display the error code and return False.
		If @error Then
			$iError = @error
			MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Server:" & @CRLF & "Could not accept the incoming connection, Error code: " & $iError)
			Return False
		EndIf
	Until $iSocket <> -1 ;if different from -1 a client is connected.

	; Close the Listening socket to allow afterward binds.
	TCPCloseSocket($iListenSocket)

	; Assign a Local variable the path of the file which will be received.
	Local $sFilePath = FileSaveDialog("Save as", @MyDocumentsDir, "All types (*.*)", BitOR($FD_PATHMUSTEXIST, $FD_PROMPTOVERWRITE))

	; If an error occurred display the error code and return False.
	If @error Then
		$iError = @error
		MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONEXCLAMATION), "", "Client:" & @CRLF & "Invalid file chosen, Error code: " & $iError)
		Return False
	EndIf

	; Assign a Local variable the handle of the file opened in binary overwrite mode.
	Local $hFile = FileOpen($sFilePath, BitOR($FO_BINARY, $FO_OVERWRITE))

	; Assign Locales Constant variables the number representing 4 KiB; the binary code for the end of the file and the length of the binary code.
	Local Const $i4KiB = 4096, $bEOF = Binary(@CRLF & "{EOF}"), $iEOFLen = BinaryLen($bEOF)

	; Assign a Local variable the empty binary data which will contain the binary data of the file.
	Local $bData = Binary("")

	; Assign a Local variable to store the length of the data received.
	Local $iDataLen = 0

	; Assign a Local variable a boolean.
	Local $fEOFReached = False

	Do
		$bData = TCPRecv($iSocket, $i4KiB, 1)

		; If an error occurred display the error code and return False.
		If @error Then
			$iError = @error
			MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Client:" & @CRLF & "Connection lost, Error code: " & $iError)
			Return False
		EndIf

		$iDataLen = BinaryLen($bData)

		; If nothing is received, retry for the incoming data.
		If $iDataLen = 0 Then ContinueLoop

		; If the end of the file is reached.
		If BinaryMid($bData, 1 + $iDataLen - $iEOFLen, $iEOFLen) = $bEOF Then
			; Strip the EOF code from the file data.
			$bData = BinaryMid($bData, 1, $iDataLen - $iEOFLen)

			; Set the EOFReached to True.
			$fEOFReached = True
		EndIf

		FileWrite($hFile, $bData)
	Until $fEOFReached

	; Close the file handle.
	FileClose($hFile)

	; Display the successful message.
	MsgBox($MB_SYSTEMMODAL, "", "Client:" & @CRLF & "File received.")

	; Close the socket.
	TCPCloseSocket($iSocket)
EndFunc   ;==>Example

Func OnAutoItExit()
	TCPShutdown() ; Close the TCP service.
EndFunc   ;==>OnAutoItExit

Attachments (0)

Change History (5)

comment:1 Changed 6 years ago by FireFox

  • Description modified (diff)
  • Owner set to FireFox
  • Status changed from new to assigned

comment:2 Changed 6 years ago by FireFox

There's no issue.

I agree in main cases it should be the client who sends the file to the server, and not the contrary, so it will be modified.

comment:3 follow-up: Changed 6 years ago by AoRaToS

The examples as they are in the documentation work for 127.0.0.1 but when you try them over a network there are issues, that's what I meant by "issue".

comment:4 in reply to: ↑ 3 Changed 6 years ago by anonymous

Replying to AoRaToS:

but when you try them over a network there are issues

I don't see any issues with the examples.

I tried yours but the schema is incorrect: When the connection is etablished while the server choose where to save the file, the client sends data in the void.

After that I always get connection lost.

comment:5 Changed 6 years ago by guinness

  • Resolution set to No Bug
  • Status changed from assigned to closed

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as closed The owner will remain FireFox.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.