找回密码
 加入
搜索
查看: 5615|回复: 6

[网络通信] TCPRecv函数[已解决]

  [复制链接]
发表于 2011-5-4 16:34:49 | 显示全部楼层 |阅读模式
本帖最后由 love5173 于 2011-5-4 22:58 编辑

以下是帮助里的一个例子,我在接受数据的时候发现如果是汉字,就只接受到第一个字,如果是数字或者字母就能完整接收,这是为什么啊,看过其他人的例子,是现在客户机转化为二进制后发送的,服务器再把二进制的数据还原字符。跟这个有关系么
#include <GUIConstantsEx.au3>

Opt('MustDeclareVars', 1)

;==============================================
;==============================================
;首先启动服务器 !!!!!!!!!!!!!!!
;==============================================
;==============================================

Example()

Func Example()
    ; 设置一些可再用的信息
    ; 在这里设置您的公共IP地址 (@IPAddress1).
;   Local $szServerPC = @ComputerName
;   Local $szIPADDRESS = TCPNameToIP($szServerPC)
    Local $szIPADDRESS = @IPAddress1
    Local $nPORT = 33891
    Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Local $msg, $recv

    ; 启动 TCP 服务
    ;==============================================
    TCPStartup()

    ; 建立监听套接字 "SOCKET".
    ;   使用您的IP地址和端口 33891.
    ;==============================================
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

    ; 如果套接字创建失败, 则退出.
    If $MainSocket = -1 Then Exit


    ; 创建消息 GUI
    ;==============================================
    $GOOEY = GUICreate("我的服务器 (IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()


    ; 初始化一个代表连接的变量,
    ;==============================================
    $ConnectedSocket = -1


    ;等待和接受连接
    ;==============================================
    Do
        $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1


    ; 获取已连接用户端接的 IP 
    $szIP_Accepted = SocketToIP($ConnectedSocket)

    ; 消息循环 GUI 
    ;==============================================
    While 1
        $msg = GUIGetMsg()

        ; 关闭 GUI 
        ;--------------------
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop

        ; 尝试最多接收 2048 字节
        ;----------------------------------------------------------------
        $recv = TCPRecv($ConnectedSocket, 2048)

        ; 如果接受失败, 则断开套接字 "socket" 
        ;----------------------------------------------------------------
        If @error Then ExitLoop

        ; 用我们接收的数据更新编辑控件
        ;----------------------------------------------------------------
        If $recv <> "" Then GUICtrlSetData($edit, _
                $szIP_Accepted & " > " & $recv & @CRLF & GUICtrlRead($edit))
    WEnd


    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

    TCPShutdown()
EndFunc   ;==>Example

; 函数将从一个连接套接字返回IP地址
;----------------------------------------------------------------------
Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "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   ;==>SocketToIP
 楼主| 发表于 2011-5-4 19:06:17 | 显示全部楼层
尝试在汉字字符串后面加了若干空格,就能完整接收了,这个是什么原因
 楼主| 发表于 2011-5-4 19:44:07 | 显示全部楼层
真的都这么冷漠吗,大家都不用这个命令的吗
发表于 2011-5-4 20:30:20 | 显示全部楼层
调用TCPSend发送数据时,AutoIt实际会在其内部 调用Ws2_32.send函数,如果发送的数据是文本字符串,那么在调用Ws2_32.send函数之前,AutoIt会先计算字符串的长度,注意这里的“字符串长度”,AutoIt内部会计算成字符数量,而不是字符串所占用的字节长度,而Ws2_32.send函数需要的是“字节长度”。比如发送“你好”,这个字符串所占用的字节数量是4(因为1个全角字符占用2个字节),可是AutoIt内部却将2(字符数量)传递给了send函数,所以实际被 复制进发送缓存区中的只有前2个字节,也就是只有“你”。

解决方法如楼主1#说的,发送前将文本转换为二进制,接收后再次转换。或者,自己调用系统函数。
 楼主| 发表于 2011-5-4 22:58:03 | 显示全部楼层
回复 4# pusofalse
P版得回复总是无可挑剔,其实看到别人的解决方式了,只是觉得函数本身怎么会出现这个问题呢,谢谢
发表于 2011-5-5 07:06:26 | 显示全部楼层
佩服P版
发表于 2012-9-11 07:16:49 | 显示全部楼层
记号.中文后再发送.接收后转换
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-6-2 18:29 , Processed in 0.079437 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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