本帖最后由 jycel 于 2009-9-24 10:31 编辑
如图,服务端写成界面,只不过方便现在检查错误
在$Combo这个发送对像中,临时设置的几个IP地址,其中所有人是必须的
在测试过程中,对所有人发送信息测试成常,但是如果对指定IP却发送成功,接收不到,在发送同时自己也会收到发送的消息如图所示
在发送信息时,我是以“接收对像|消息|本机IP”来定义
服务端接收数据通过StringSplit拆分分为三份,如果值[1]为所有人,就转发给所有人。如果非所有人,就发送给值一IP
请大家帮忙检查下问题出在那儿了,谢谢!
解决方法:需要修改的地方,其实答案就在以前的代码中~
If $lh[1]<>"所有人" Then
$iIndex = _ArraySearch($aConnected, $lh[1], 1, 0, 0, 0, 1, 1)
$sMsg = StringToBinary($lh[2]&"|"&$lh[3], 4)
TCPSend($aConnected[$iIndex][0], $sMsg) ; 发送信息
;TCPSend($lh[1], $sMsg)
If @error Then
GUICtrlSetData($Label1, "消息转发失败!")
Else
GUICtrlSetData($Label1, "消息转发成功!")
EndIf
Else
$sMsg = StringToBinary($lh[2]&"|"&$lh[3], 4)
For $i = 1 To $aConnected[0][0]
$iIP = $aConnected[$i][1]
TCPSend($aConnected[$i][0], $sMsg)
Next
GUICtrlSetData($Label1, "群发消息转发成功!")
EndIf
服务端源码:
#include <ComboConstants.au3>
#include <GUIConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
Global $Edit1,$Edit2, $Edit3, $Combo1, $Label1
Local $sSrvIP = @IPAddress1, $iPort = 65432
#Region ### START Koda GUI section ### Form=c:\documents and settings\administrator\桌面\tcp.kxf
$Form1 = GUICreate("TCP-Server", 522, 327, 522, 398)
$Group1 = GUICtrlCreateGroup("", 8, 0, 505, 318)
$Edit1 = GUICtrlCreateEdit("历史消息:"&"本机用户名→"&@ComputerName, 16, 16, 489, 20,BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN,$WS_HSCROLL))
GUICtrlSetState(-1,$GUI_DISABLE)
$Edit2 = GUICtrlCreateEdit("", 16, 40, 489, 217,BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN,$WS_VSCROLL))
;GUICtrlSetState(-1,$GUI_DISABLE)
$Label1 = GUICtrlCreateLabel("", 16, 264, 490, 17)
GUICtrlSetColor(-1, 0xFF0000)
$Label2 = GUICtrlCreateLabel("→", 16, 292, 19, 17)
GUICtrlSetColor(-1, 0x000080)
$Combo1 = GUICtrlCreateCombo("", 40, 288, 105, 25)
GUICtrlSetData(-1,"所有人|192.168.0.55|192.168.0.136|192.168.0.254","所有人")
$Edit3 = GUICtrlCreateEdit("", 152, 288, 273, 20, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN))
$Button1 = GUICtrlCreateButton("发送", 432, 288, 73, 20, $BS_DEFPUSHBUTTON)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Global $MainSocket, $aConnected[1][2] = [[0]]
TCPStartUp()
$MainSocket = TCPListen($sSrvIP, $iPort, 100)
If $MainSocket = -1 Then Exit ; 创建监听不成功就退出
GUICtrlSetData($Label1, "正在等待客户端连接……")
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
_ext()
Case $Button1
_send()
EndSwitch
Accept()
Recv()
WEnd
Exit
Func _ext()
TCPCloseSocket($MainSocket)
TCPShutdown()
Exit
EndFunc
Func _send()
Local $sMsg, $iIP, $iIndex, $sEdit
$sMsg = GUICtrlRead($Edit3)
$iIP =GUICtrlRead($Combo1)
$iIndex = _ArraySearch($aConnected, $iIP, 1, 0, 0, 0, 1, 1)
If $sMsg = "" Then
GUICtrlSetData($Label1, "消息不能为空!")
ElseIf $iIP = "所有人" Then ; 未输入IP,开始广播
$sEdit = "→【"&GUICtrlRead($Combo1)&"】:"& $sMsg & @CRLF & GUICtrlRead($Edit2)
GUICtrlSetData($Edit2, $sEdit)
$sMsg = StringToBinary($sMsg, 4)
For $i = 1 To $aConnected[0][0]
$iIP = $aConnected[$i][1]
TCPSend($aConnected[$i][0], $sMsg)
Next
GUICtrlSetData($Label1, "广播完毕! 当前连接: " & $aConnected[0][0])
ElseIf $iIndex = -1 Then
GUICtrlSetData($Label1, $iIP & " 客户端尚未连接!")
Else
$sEdit = $iIP & " > " & $sMsg & @CRLF & GUICtrlRead($Edit2)
GUICtrlSetData($Edit2, $sEdit)
$sMsg = StringToBinary($sMsg, 4)
TCPSend($aConnected[$iIndex][0], $sMsg) ; 发送信息
If @error Then
GUICtrlSetData($Label1, $iIP & " 消息发送失败!")
Else
GUICtrlSetData($Label1, $iIP & " 消息发送成功!")
EndIf
EndIf
GUICtrlSetData($Edit3, "")
GUICtrlSetState($Edit3, $GUI_FOCUS)
Return
EndFunc
Func Accept()
Local $ConnectedSocket, $sEdit
$ConnectedSocket = TCPAccept($MainSocket)
If $ConnectedSocket <> -1 Then
$aConnected[0][0] += 1
ReDim $aConnected[$aConnected[0][0] + 1][2]
$aConnected[$aConnected[0][0]][0] = $ConnectedSocket
$aConnected[$aConnected[0][0]][1] = SocketToIP($ConnectedSocket)
;$sEdit = "→【" & $aConnected[$aConnected[0][0]][1] & "】:上线"& @CRLF & GUICtrlRead($Edit2)
;GUICtrlSetData($Edit2, $sEdit)
GUICtrlSetData($Label1, "")
GUICtrlSetData($Label1, "【" & $aConnected[$aConnected[0][0]][1] & "】:连接成功!")
EndIf
Return
EndFunc
Func Recv()
Local $sRecv, $sEdit, $i = 1
While $i <= UBound($aConnected) - 1
$sRecv = TCPRecv($aConnected[$i][0], 2048, 1);256)
If @error Then ; 客户端已关闭
;$sEdit = "→【" & $aConnected[$i][1] & "】:下线"& @CRLF & GUICtrlRead($Edit2)
;GUICtrlSetData($Edit2, $sEdit)
GUICtrlSetData($Label1, "")
GUICtrlSetData($Label1, "【" & $aConnected[$i][1] & "】:已退出")
TCPCloseSocket($aConnected[$i][0])
_ArrayDelete($aConnected, $i)
$aConnected[0][0] -= 1
Else
If $sRecv <> "" Then ; 接收到客户端发送数据,开始处理
$sRecv = BinaryToString($sRecv, 4)
$sEdit = "→【" & $aConnected[$i][1] & "】: " & $sRecv & @CRLF & GUICtrlRead($Edit2)
$lh=StringSplit($sRecv,"|")
If $lh[1]<>"所有人" Then
$sMsg = StringToBinary($lh[2]&"|"&$lh[3], 4)
TCPSend($lh[1], $sMsg)
TCPSend($lh[3], $sMsg)
GUICtrlSetData($Label1,"向"&$lh[1]&"转发成功 向"&$lh[1]&"回复成功")
Else
$sMsg = StringToBinary($lh[2]&"|"&$lh[3], 4)
For $i = 1 To $aConnected[0][0]
$iIP = $aConnected[$i][1]
TCPSend($aConnected[$i][0], $sMsg)
Next
EndIf
GUICtrlSetData($Edit2, $sEdit)
EndIf
$i += 1
EndIf
WEnd
Return
EndFunc
; Function to return IP Address from a connected socket.
;----------------------------------------------------------------------
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
Return $aRet
EndFunc ;==>SocketToIP
客户端:
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Global $Edit1, $Edit2, $Label1
Local $sRecv, $sEdit, $sSrvIP, $iPort = 65432
$sSrvIP = "192.168.0.136"
#Region ### START Koda GUI section ### Form=c:\documents and settings\administrator\桌面\tcp.kxf
$Form1 = GUICreate("TCP-Client", 522, 327, 522, 398)
$Group1 = GUICtrlCreateGroup("", 8, 0, 505, 318)
$Edit1 = GUICtrlCreateEdit("历史消息:"&"本机用户名→"&@ComputerName, 16, 16, 489, 20, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN))
GUICtrlSetState(-1,$GUI_DISABLE)
$Edit2 = GUICtrlCreateEdit("", 16, 40, 489, 217, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN))
$Label1 = GUICtrlCreateLabel("正在连接……", 16, 264, 490, 17)
GUICtrlSetColor(-1, 0xFF0000)
$Label2 = GUICtrlCreateLabel("→", 16, 292, 19, 17)
GUICtrlSetColor(-1, 0x000080)
$Combo1 = GUICtrlCreateCombo("", 40, 288, 105, 25)
GUICtrlSetData(-1,"所有人|192.168.0.65|192.168.0.136|192.168.0.254","所有人")
$Edit3 = GUICtrlCreateEdit("", 152, 288, 273, 20, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN))
$Button1 = GUICtrlCreateButton("发送", 432, 288, 73, 20)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
;-------------------------------------------
Global $Socket
TCPStartUp()
$Socket = TCPConnect($sSrvIP, $iPort) ; 创建一个套接字连接到已经存在的服务器
If $Socket = -1 Then
MsgBox(0, "提示", "服务端未开启请联系管理员!", 0, $Form1)
_ext()
EndIf
GUICtrlSetData($Label1, "连接["&$sSrvIP&"]服务器成功")
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
_ext()
Case $Button1
_send()
EndSwitch
$sRecv = TCPRecv($Socket, 2048, 1)
If @error Then
MsgBox(0, "提示", "服务端已关闭!", 0, $Form1)
_ext()
ElseIf $sRecv <> "" Then ; 把接收的内容放到文本框内
$sRecv = BinaryToString($sRecv, 4)
$lh=StringSplit($sRecv,"|")
$sEdit = "→【"& $lh[2] & "】: " & $lh[1] & @CRLF & GUICtrlRead($Edit2)
GUICtrlSetData($Edit2, $sEdit)
EndIf
WEnd
Exit
;-------------------------------------------
Func _ext()
TCPCloseSocket($Socket)
TCPShutdown()
Exit
EndFunc
;-------------------------------------------
Func _send()
Local $sMsg, $sEdit
$sMsg = GUICtrlRead($Edit3)
If $sMsg = "" Then
GUICtrlSetData($Label1, "消息不能为空!")
Else
$sEdit = "→【"&GUICtrlRead($Combo1)&"】:"& $sMsg & @CRLF & GUICtrlRead($Edit2)
;GUICtrlSetData($Edit2, $sEdit)
$sMsg = StringToBinary(GUICtrlRead($Combo1)&"|"&$sMsg&"|"&@IPAddress1, 4)
TCPSend($Socket,$sMsg) ; 发送信息
If @error Then
GUICtrlSetData($Label1, "消息发送失败!")
Else
GUICtrlSetData($Label1, "消息发送成功!")
EndIf
EndIf
GUICtrlSetData($Edit3, "")
GUICtrlSetState($Edit3, $GUI_FOCUS)
Return
EndFunc
|