|
Server
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiIPAddress.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("服务端", 395, 172, 192, 132)
$Input1 = GUICtrlCreateInput("10073", 64, 24, 49, 24)
$Label1 = GUICtrlCreateLabel("端口", 24, 24, 35, 20)
$IPAddress1 = _GUICtrlIpAddress_Create($Form1, 192, 24, 137, 25)
_GUICtrlIpAddress_Set($IPAddress1, "127.0.0.1")
$Label2 = GUICtrlCreateLabel("IP地址", 136, 24, 55, 20)
$Button1 = GUICtrlCreateButton("启动服务", 48, 120, 97, 33)
$Button2 = GUICtrlCreateButton("停止服务", 210, 120, 97, 33)
$Label3 = GUICtrlCreateLabel("服务状况", 130, 72, 210, 20)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Dim $g_IP,$port,$id,$i,$data,$ConnectedSocket,$MainSocket,$h,$HFile,$j,$f,$ip,$say,$n,$data1,$HFile1,$t
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
$port=GUICtrlRead($Input1)
TCPStartUp() ;启动TCP服务
$MainSocket = TCPListen(_GUICtrlIpAddress_Get($IPAddress1), $port, 100 )
If $MainSocket = -1 Then
MsgBox(0,"错误提示",@error)
Else
GUICtrlSetData($Label3,"服务已启动")
GUICtrlSetState($Button1,$GUI_DISABLE)
CustomerAccess() ;自定义函数
EndIf
Case $Button2
TCPShutdown()
EndSwitch
WEnd
Func CustomerAccess()
; 循环监听服务端口
Do
If $t<>1 Then
$ConnectedSocket = TCPAccept($MainSocket)
GUICtrlSetData($Label3,"正在监听中..")
EndIf
;循环中 如果有用户操作界面 可以在这里获取到用户消息,并处理
$msg = GuiGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
CLOSE()
Case $msg = $Button2
TCPShutdown()
GUICtrlSetData($Label3,"服务已停止")
MsgBox(0,"提示","程序关闭后,重新运行才能启动服务!")
Exit
EndSelect
;当监听到有客户进去,跳出循环 ,进入下一循环获取数据
Until $ConnectedSocket <> -1
;$ip=SocketToIP($ConnectedSocket) 这里是获取客户IP
;$HFile=FileOpen (@ScriptDir&""&$ip&".jpg",18) 更具客户IP 命名上传到服务器文件的名称,创建文件,也可以根据后边的代码,来创建
While 1
;获取用户数据,这里还有有一个参数 1 表述强制转换为二进制数据,因为我传输的数据时已经区分了 这里不需要强制
$data=TCPRecv($ConnectedSocket,1024*1000)
;这里说明一下 错误的取值如果是-1的话 都是因为客户端主动断开
If @error Then ; 其他值请参考 MSDN;
FileClose($HFile) ; 一般断开的原因是 文件传输完毕了,客户端主动断开,所以这里我们关闭文件句柄
ExitLoop ;跳出循环
EndIf
If $data<>"" Then
;如果数据不为空的话,首先判断 此数据是字串符,这个判断很重要哦
If 0=IsBinary($data) Then
;如果是字串符,OK 明白了 这是客户端发送的文件的名称数据,我们来分隔字串符,获取文件名称
$say=StringSplit($data,"",1) ;这里有个BUG,就是如果文件名是汉字,将获取不完全,请高手指正
$n=$say[0]
$HFile1=FileOpen (@ScriptDir&""&$say[$n],18) ; 获取文件句柄
Else
;$h=FileWrite($HFile,Binary($data))
$h=FileWrite($HFile1,Binary($data)) ;向文件写入数据
$f=BinaryLen ($data)
$j=$j+$f
If $h=1 Then GUICtrlSetData($Label3,"正在写入数据---"&$j)
EndIf
Else
GUICtrlSetData($Label3,"客户进入,准备接受客户端数据")
EndIf
;循环中 如果有用户操作界面 可以在这里获取到用户消息,并处理
$msg = GuiGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
CLOSE()
Case $msg = $Button2
TCPShutdown()
GUICtrlSetData($Label3,"服务已停止")
GUICtrlSetState($Button1,$GUI_ENABLE)
MsgBox(0,"提示","程序关闭后,重新运行才能启动服务!")
Exit
EndSelect
WEnd
$data=""
If $ConnectedSocket <> -1 Then
GUICtrlSetData($Label3,"正在写入数据")
GUICtrlSetData($Label3,"断开与客户端连接")
TCPCloseSocket($ConnectedSocket)
;FileClose($HFile)
FileClose($HFile1)
CustomerAccess() ; 归递法,放创建完文件后 继续监听下一个客户的到来
EndIf
EndFunc
Func CLOSE()
Exit
EndFunc
Func SocketToIP($SHOCKET) ;获取客户IP
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
Client
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiIPAddress.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("窗体1", 405, 178, 204, 186)
$IPAddress1 = _GUICtrlIpAddress_Create($Form1, 32, 24, 130, 25)
_GUICtrlIpAddress_Set($IPAddress1, "127.0.0.1")
$Input1 = GUICtrlCreateInput("10073", 200, 24, 57, 24)
$Button1 = GUICtrlCreateButton("连接", 296, 24, 65, 25)
$Button2 = GUICtrlCreateButton("发送数据", 136, 120, 97, 33)
$Label1 = GUICtrlCreateLabel("IP", 8, 24, 16, 20)
$Label2 = GUICtrlCreateLabel("port", 168, 24, 30, 20)
$Input2 = GUICtrlCreateInput("", 24, 72, 289, 24)
$Button3 = GUICtrlCreateButton("打开", 328, 72, 49, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Dim $i,$file,$id,$data,$data1
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
TCPStartup()
$i=TCPConnect(_GUICtrlIpAddress_Get($IPAddress1),GUICtrlRead($Input1))
If $i=-1 Then
MsgBox(0,"",@error)
EndIf
Case $Button2
$data1=TCPSend($i,$file) ;发送文件名,给服务端 ,我是发送的真个路劲当然你也可以在这里拆分,在发送
Sleep(1000)
If $data1<>"" Then Senddata($i,$file,2048) ;自定义函数 用来发送数据的
Case $Button3
$file=FileOpenDialog("请选择一个图片",@WindowsDir & "", "(*.*)", 1 + 4 )
;If $file<>"" Then
;$id=FileOpen($file,16)
GUICtrlSetData($Input2,$file)
; $data=FileRead($id)
;EndIf
; If $data="" Then MsgBox(0,"警告","没有找到可用文件")
EndSwitch
WEnd
Func Senddata($netid,$hfile,$max) ;自定函数的参数值 分别是 套接字标识,文件路径,每次获取文件数据的最大值多少
$id=FileOpen($hfile,16) ;以二进制的形式打开文件,让后续读取到的数据都是二进制的
While 1 ;循环读取文件数据并发送
$data=FileRead($id,$max)
If @error=-1 Then ;获取错误代码 如果是-1 则代表 以到文件尾部,则跳出循环
ExitLoop
EndIf
TCPSend($netid,$data)
WEnd
$data="" ;清空变量
TCPCloseSocket($netid) ; 关闭连接,好让别人传送数据啊 ,唉不是多线程啊 没办法
EndFunc
使用以上代码来发送text文档,接收端只有收到文件,但是文件的内容没有发送过来。
请高手帮忙看看。我现在也是一头雾水啊 |
|