wingking84 发表于 2012-6-7 17:42:15

TCP SERVER自动结束运行

本帖最后由 wingking84 于 2012-6-26 12:10 编辑

说明:(脚本都在本机运行)
1 CLINET 弹出 INPUT, 输入字符串,发送给SERVER
2 SERVER 接收到后,写到EDIT中,并把字符串发回给CLIENT.
3 CLIENT收到后,msgbox,
问题:点击msgbox确定后,SERVER自动结束运行了。(SERVER脚本先编译成EXE)
期望:SERVER一直运行。SERVER:

While 1
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
        $recv = TCPRecv($ConnectedSocket, 2048)
        If @error Then ExitLoop
        If $recv <> "" Then
                GUICtrlSetData($edit, $recv & @CRLF & GUICtrlRead($edit))
                TCPSend($ConnectedSocket,$recv & " from server")
        EndIf       
WEnd

If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)
TCPShutdown()
CLIENT:
    If @error Then
      MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error)
    Else

                TCPSend($ConnectedSocket, $szData)               

      While 1
                        $recv = TCPRecv($ConnectedSocket, 2048)
                        If $recv <> "" Then
                                $recv = BinaryToString($recv)
                                MsgBox(0,"receive",$recv)
                                ExitLoop
                        EndIf

            If @error Then ExitLoop
      WEnd
    EndIf

xms77 发表于 2012-6-7 17:42:16

回复 1# wingking84
注释掉第7行代码试试。

user3000 发表于 2012-6-7 19:56:24

服务端持续运行! 同一机器可运行多个客户端, 并独立地与服务端进行通讯!
应该达到你的要求了!

服务端代码:
;;';SERVER:
$Form1 = GUICreate("服务端", 638, 521)
$edit = GUICtrlCreateEdit('', 8, 8, 625, 511)
Local $sSrvIP = @IPAddress1, $iPort = 65432
Global $MainSocket, $aConnected = []
TCPStartUp()
$MainSocket = TCPListen($sSrvIP, $iPort, $iPort)
If $MainSocket = -1 Then Exit
GUICtrlSetData($edit, "状态正常!", 1)
GUISetState(@SW_SHOW)

While 1
        Sleep(100)
        Accept()
        Recv()
WEnd
;TCPShutdown()

Func Accept()
        Local $ConnectedSocket, $sEdit
        $ConnectedSocket = TCPAccept($MainSocket)
        If $ConnectedSocket <> -1 Then
                $aConnected += 1
                ReDim $aConnected[$aConnected + 1]
                $aConnected[$aConnected] = $ConnectedSocket
                $aConnected[$aConnected] = SocketToIP($ConnectedSocket)
                EndIf
        Return
EndFunc

Func Recv()
        Local $sRecv, $sEdit, $i = 1,$hQuery,$aRow,$cids
        While $i <= UBound($aConnected) - 1
                $sRecv = TCPRecv($aConnected[$i], 2048, 1);
                        If $sRecv <> "" Then   
                        $sRecv = BinaryToString($sRecv, 4)                               
            GUICtrlSetData($edit, 'From ' & $aConnected[$i] & ': ' & $sRecv & @CRLF, 1)
                        TCPSend($aConnected[$i],$sRecv & " from server")
            EndIf
                        $i += 1
        WEnd               
        Return
EndFunc

Func SocketToIP($Shocket)
        Local $SockAddr, $aRet
        $SockAddr = DllStructCreate("short;ushort;uint;char")
        $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $Shocket, "ptr", DllStructGetPtr($SockAddr), "int*", DllStructGetSize($SockAddr))
        If NOT @error AND $aRet = 0 Then
                $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($SockAddr, 3))
                If NOT @error Then $aRet = $aRet
        Else
                $aRet = 0
        EndIf
        Return $aRet
EndFunc   ;==>SocketToIP

客户端代码:
Local $sSrvIP = @IPAddress1, $iPort = 65432, $Socket
$Form1 = GUICreate('Client', 516, 316)
$edit = GUICtrlCreateEdit('', 8, 8, 500, 200)
$but = GUICtrlCreateButton('发送', 150, 230, 75, 28)
GUISetState(@SW_SHOW)
TCPStartup()
$Socket = TCPConnect($sSrvIP, $iPort) ; 创建一个套接字连接到已经存在的服务器
If $Socket = -1 Then
        MsgBox(0, "提示", "服务端未开启! ")
        _Exit()
EndIf

While 1
        Switch GUIGetMsg()
                Case -3
                        _exit()
                Case $but
                        _send()
        EndSwitch
WEnd

Func _Exit()
        TCPCloseSocket($Socket)
        Exit
EndFunc   ;==>_Exit

Func _send()
        $sMsg = GUICtrlRead($edit)
        If $sMsg = "" Then Return MsgBox(16, 'Err', '请先输入数据! ', '', $Form1)
        TCPSend($Socket, StringToBinary($sMsg)) ; 发送信息
        While 1
                $recv = TCPRecv($Socket, 2048)
                If $recv <> "" Then
                        $recv = BinaryToString($recv)
                        MsgBox(0, "receive", $recv)
                        ExitLoop
                EndIf
        WEnd
        Return       
EndFunc   ;==>_send

xms77 发表于 2012-6-7 21:47:59

回复 2# user3000
一直用UDP,从来没有用过TCP,今天学习一下TCP看看,谢谢你的代码!

user3000 发表于 2012-6-7 21:56:46

回复 4# xms77

不能说是我的代码了, 论坛上好多关于'TCP'的应用例子. 它们在TCP通讯上,大同小异.
我只是弄了一个简化版本, 给楼主举个例子.

xms77 发表于 2012-6-7 22:01:03

回复 2# user3000
SocketToIP()这个函数没有看懂,对于数据结构还是一知半解,DLLCall也是。

user3000 发表于 2012-6-7 22:24:49

回复 6# xms77
汗, 我可能比你还不如呢, 对这从来没怎么上心过! 都是'拿来主义'!
其实这函数, 在自定义函数里也有,参见: TCPRecv().
我也仅知道它是获取当前已建立连接的'客户端'的IP.

ailfawang 发表于 2012-6-7 22:29:50

学习学习,看不懂

ye5022 发表于 2017-9-16 19:05:45

高手, 郑找这方面的资料呢
页: [1]
查看完整版本: TCP SERVER自动结束运行