Opened 12 years ago
Closed 12 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 12 years ago by FireFox
- Description modified (diff)
- Owner set to FireFox
- Status changed from new to assigned
comment:2 Changed 12 years ago by FireFox
comment:3 follow-up: ↓ 4 Changed 12 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 12 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 12 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.


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.