找回密码  加入

AUTOIT CN

搜索
查看: 193|回复: 4

[网络通信] [以解决]我在论坛找的TCP通信例子,为什么打开发送端,接收端就会自己关闭呢?

[复制链接]
发表于 2019-2-1 15:43:57 | 显示全部楼层 |阅读模式
本帖最后由 aryce 于 2019-2-3 20:33 编辑

我在论坛找的TCP通信例子,为什么打开发送端,接收端就会自己关闭呢?第一次学习tcp通信, 希望大神能帮忙解答一下
版本3.3.9.21
系统win7x64

服务端:
  1. #include <GUIConstantsEx.au3>
  2. #include <WindowsConstants.au3>

  3. Local $szIPADDRESS = "192.168.20.89";你的公共IP地址
  4. Local $nPORT = 33891;端口
  5. Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
  6. Local $msg, $recv

  7. TCPStartup()
  8. $MainSocket = TCPListen($szIPADDRESS, $nPORT)
  9. $GOOEY = GUICreate("My Server (IP: " & $szIPADDRESS & ")", 300, 200)
  10. $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
  11. GUISetState()
  12. $ConnectedSocket = -1
  13. Do
  14.         $ConnectedSocket = TCPAccept($MainSocket)
  15. Until $ConnectedSocket <> -1

  16. While 1
  17.         $ConnectedSocket = TCPAccept($MainSocket)
  18.         $msg = GUIGetMsg()
  19.         If $msg = $GUI_EVENT_CLOSE Then ExitLoop
  20.         $recv = TCPRecv($ConnectedSocket, 2048)
  21.         If @error Then ExitLoop
  22.         If $recv <> "" Then GUICtrlSetData($edit, $recv & @CRLF & GUICtrlRead($edit))
  23. ;~                 If $ConnectedSocket <> -1 Then Exit
  24.                
  25. WEnd

  26. If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)
  27. TCPShutdown()
复制代码
客户端:
  1. #Region ;**** 参数创建于 ACNWrapper_GUI ****
  2. #PRE_Icon=C:\Windows\syswow64\SHELL32.dll
  3. #PRE_UseX64=n
  4. #PRE_Res_requestedExecutionLevel=None
  5. #EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
  6. #include <GUIConstantsEx.au3>
  7. #include <WindowsConstants.au3>

  8. Local $ConnectedSocket, $szData
  9. Local $szIPADDRESS = "192.168.20.89"
  10. Local $nPORT = 33891
  11. TCPStartup()
  12. $ConnectedSocket = -1
  13. $ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
  14. If @error Then
  15.         MsgBox(4112, "错误", "TCP连接失败,服务端未启用!错误代码: " & @error)
  16. Else
  17.         While 1
  18.                 $szData = InputBox("发送数据给服务端", @LF & @LF & "输入一个要发送给服务端的数据:")
  19.                 If @error Or $szData = "" Then ExitLoop
  20.                 TCPSend($ConnectedSocket, $szData)
  21.                 If @error Then ExitLoop
  22.         WEnd
  23. EndIf
复制代码




发表于 2019-2-1 16:28:29 | 显示全部楼层
本帖最后由 水木子 于 2019-2-1 16:37 编辑

新年快乐!
这东西我之前研究过,这是我之前练习写着玩的代码,代码都有注释,应该好理解,希望对你有点帮助吧!
为此我还专门写过一个聊天工具呢!


接收端:
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

;~ 我是服务端,请先启动我。

TCPStartup() ; 启动 TCP 服务.

; 注册脚本关闭时调用的退出函数 OnAutoItExit().
OnAutoItExitRegister('OnAutoItExit')

; 分配局部变量回送 IP 地址和端口.
Global $sIPAddress = @IPAddress1 ; 此 IP 地址仅用于在您自己的计算机上测试.
Global $iPort = 65432 ; 用于连接的端口.

$hGui1 = GUICreate('服务端 (IP: ' & $sIPAddress & ')', 400, 300)
$Edit1 = GUICtrlCreateEdit('', 10, 10, 380, 280)
GUISetState()

_TCPServer_RecvData($sIPAddress, $iPort)

Func _TCPServer_RecvData($sIPAddress, $iPort)
        ; 分配一个局部变量套接字并绑定到的IP地址和端口, 指定最多 100 个挂起的联接.
        Local $iListenSocket = TCPListen($sIPAddress, $iPort, 100)
        Local $iError = 0
        Local Const $iMaxLen = 1024 * 1024

        If @error Then
                ; 可能有人已经在侦听此 IP 地址和端口(脚本已经在运行吗?).
                $iError = @error
                MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), '', '服务器:' & @CRLF & '不能接听, 错误代码: ' & $iError)
                Return False
        EndIf

        ; 指定客户端使用的套接字到本地变量.
        Local $iSocket = 0

        Do ; 等待有人来连接 (无限制).
                ; 接受存在的传入联接(完成时关闭套接字; 每个客户端一个套接字).
                $iSocket = TCPAccept($iListenSocket)

                ; 如果发生错误, 则显示错误代码, 并返回 False.
                If @error Then
                        $iError = @error
                        MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), '', '服务器:' & @CRLF & '不能接收传入的连接,错误代码: ' & $iError)
                        Return False
                EndIf
                
                If $iSocket <> -1 Then
                        $sReceived = TCPRecv($iSocket, $iMaxLen, 1)
                        If $sReceived <> '' Then GUICtrlSetData($Edit1, BinaryToString($sReceived, 4), 1)
                EndIf

        Until GUIGetMsg() = -3 ;如果不是 -1 则是一个客户端连接.

        ; 关闭侦听套接字允许之后绑定.
        TCPCloseSocket($iListenSocket)

        ; 关闭套接字.
        TCPCloseSocket($iSocket)
EndFunc   ;==>_TCPServer_RecvData

Func SocketToIP($iSocket)
        Local $tSockAddr, $aRet
        $tSockAddr = DllStructCreate('short;ushort;uint;char[8]')
        $aRet = DllCall('Ws2_32.dll', 'int', 'getpeername', 'int', $iSocket, 'struct*', $tSockAddr, 'int*', DllStructGetSize($tSockAddr))
        If Not @error And $aRet[0] = 0 Then
                $aRet = DllCall('Ws2_32.dll', 'str', 'inet_ntoa', 'int', DllStructGetData($tSockAddr, 3))
                If Not @error Then Return $aRet[0]
        EndIf
        Return 0
EndFunc   ;==>SocketToIP

Func OnAutoItExit()
        TCPShutdown() ; 关闭 TCP 服务.
EndFunc   ;==>OnAutoItExit


发送端:
#include <GuiIPAddress.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

;~ 我是客户端,请先启动服务端。
;~ ShellExecute(@ScriptDir & '\服务端.au3')

TCPStartup() ; 启动 TCP 服务.

; 注册脚本关闭时调用的退出函数 OnAutoItExit().
OnAutoItExitRegister('OnAutoItExit')

; 分配局部变量回送 IP 地址和端口.
Global $sIPAddress = @IPAddress1 ; 此 IP 地址仅用于在您自己的计算机上测试.
Global $iPort = 65432 ; 用于连接的端口.

$hGui1 = GUICreate('客户端 (IP: ' & $sIPAddress & ')', 400, 300)
$Edit1 = GUICtrlCreateEdit('', 10, 10, 380, 200)

GUICtrlCreateLabel('服务端IP:', 10, 230, 60, 17)
$IPAddress1 = _GUICtrlIpAddress_Create($hGui1, 70, 226, 130, 21)
_GUICtrlIpAddress_Set($IPAddress1, @IPAddress1)
GUICtrlCreateLabel(':', 210, 230, 10, 17)
$Input1 = GUICtrlCreateInput('65432', 225, 226, 60, 21)

GUICtrlCreateLabel('发送信息:', 10, 266, 60, 17)
$Input2 = GUICtrlCreateInput('', 70, 262, 240, 21)
$Button1 = GUICtrlCreateButton('发送', 310, 260, 80, 25)
GUISetState()

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case -3
                        Exit
                Case $Button1
                        _TCP_SendData()

        EndSwitch
WEnd

Func _TCP_SendData()
        $sIPAddress = _GUICtrlIpAddress_Get($IPAddress1)
        $iPort = GUICtrlRead($Input1)
        $sData = GUICtrlRead($Input2)
        
        If $sData <> '' Then
                If $sIPAddress = '' Then $sIPAddress = @IPAddress1
                If $iPort = '' Then $iPort = 65432
                
                $sData = $sIPAddress & ' ' & @HOUR & ':' & @MIN & ':' & @SEC & @CRLF & $sData & @CRLF & @CRLF
                _TCPClient_SendData($sIPAddress, $iPort, $sData)
                GUICtrlSetData($Edit1, $sData, 1)
                GUICtrlSetData($Input2, '')
        EndIf
EndFunc   ;==>_TCP_SendData

Func _TCPClient_SendData($sIPAddress, $iPort, $sData)
        ; 分配本地变量一个套接字, 并连接到指定侦听套接字的 IP 地址与端口.
        Local $iSocket = TCPConnect($sIPAddress, $iPort)
        Local $iError = 0

        ; 如果发生错误, 则显示错误代码, 并返回 False.
        If @error Then
                ; 该服务器可能离线或未打开服务器的端口.
                $iError = @error
                MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), '', '客户端:' & @CRLF & '无法连接, 错误代码: ' & $iError)
                Return False
        EndIf

        TCPSend($iSocket, StringToBinary($sData, 4))

        ; 如果发生错误, 则显示错误代码, 并返回 False.
        If @error Then
                $iError = @error
                MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), '', '客户端:' & @CRLF & '无法发送数据, 错误代码: ' & $iError)
                Return False
        EndIf

        ; 关闭套接字.
        TCPCloseSocket($iSocket)
EndFunc   ;==>_TCPClient_SendData

Func OnAutoItExit()
        TCPShutdown() ; 关闭 TCP 服务.
EndFunc   ;==>OnAutoItExit

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入

x

评分

1

查看全部评分

回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-2-3 20:33:12 | 显示全部楼层
水木子 发表于 2019-2-1 16:28
新年快乐!
这东西我之前研究过,这是我之前练习写着玩的代码,代码都有注释,应该好理解,希望对你有点帮 ...

非常感谢啊 ~
发表于 7 天前 | 显示全部楼层
大过年的也在研究,辛苦了。
发表于 前天 15:35 | 显示全部楼层
研究下,辛苦了。有帮助!!!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2019-2-18 04:20 , Processed in 0.103072 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表