871224 发表于 2009-12-30 10:04:07

利用TCP可以实现外网传输吗?

如下是论坛中找到的源码,局域网传输经实践可行。但是外网就不行了。#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_Icon=..\ico\2.ICO
#AutoIt3Wrapper_Outfile=..\1\TCP发送.exe
#AutoIt3Wrapper_Compression=4
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
;================================================
;本函数分为发送单元(_SendFileMsg)和接收单元(_ReceiveFileMsg),可同时发送(接收)文字信息或传送(接收)文件
;_SendFileMsg和_ReceiveFileMsg既可分开使用亦可合并到同一程序中协同使用
;提供诸多数据接口供主程序调用详见注释
;================================================
_SendFileMsg("e:\程序.exe", "192.168.1.23");这样就发送文件了(什么类型文件都可以)
;_SendFileMsg("我这里发送的多撒谎还是信息看到吗?", "192.168.1.23");这样就发送信息了

Func _SendFileMsg($SendFile, $Source_IP, $sPort = 8410);发送文件信息,默认端口8410
      Local $sSocket = -1, $sSize, $sData, $sTCPListen = -1, $sAccept = -1, $sBuff, $sFile, $sBytes = 0, $sPercent
      TCPStartup();开始UDP服务
      $sTCPListen = TCPListen(@IPAddress1, $sPort, 100);创建一个已经连接的套接字监听
      If $sTCPListen = -1 Then Return
      $sSocket = TCPConnect($Source_IP, $sPort);创建一个套接字(socket)连接到已经存在的服务器
      If $sSocket <> -1 Then
                If StringInStr($SendFile, ":\") And StringInStr($SendFile, ".") And StringInStr($SendFile, "|") = 0 Then
                        $sSize = FileGetSize($SendFile);文件总字节数接口
                        If $sSize <> 0 Then
                              $sData = StringToBinary(@IPAddress1 & "|||" & StringRegExpReplace($SendFile, '.+\\', '') & "|||" & $sSize, 4);整理文件信息
                              TCPSend($sSocket, $sData);发送确认信息字符串
                              Do
                                        $sAccept = TCPAccept($sTCPListen)
                              Until $sAccept <> -1
                              Do
                                        $sBuff = TCPRecv($sAccept, 2048);接收目标机确认信息
                              Until $sBuff <> ""
                              If $sBuff = "OK" Then;收到确认信息
                                        MsgBox(0, "提示", "对方已经确认接收文件");对方确认接收文件信息接口
                                        $sFile = FileOpen($SendFile, 16)
                                        Dim $si = 0
                                        $sSocket = TCPConnect($Source_IP, $sPort)
                                        While 1
                                                $sData = FileRead($sFile, 1024 * 1024);开始读取文件
                                                If @error = -1 Then ExitLoop;读到文件结尾后退出循环
                                                TCPSend($sSocket, $sData);发送读到的文件字节
                                                $si += BinaryLen($sData);循环次数计数器
                                                $sPercent = $si / $sSize * 100;已发送字节数百分比接口($sPercent)
                                        WEnd
                                        FileClose($sFile);关闭文件句柄
                                        If $sSocket <> -1 Then TCPCloseSocket($sSocket)
                                        MsgBox(0, "提示", "   " & StringRegExpReplace($SendFile, '.+\\', '') & "文件发送完毕!   ");文件发送完毕提示信息接口
                              ElseIf $sBuff = "NO" Then;收到拒绝信息
                                        MsgBox(0, "提示", "对方拒绝接收文件");对方拒绝接收文件信息接口
                              EndIf
                        EndIf
                        If $sAccept <> -1 Then TCPCloseSocket($sAccept)
                Else;判断发送的是信息
                        $sData = StringToBinary($SendFile, 4);转换字符串到二进制数据发送信息
                        TCPSend($sSocket, $sData);发送字符串
                        If $sSocket <> -1 Then TCPCloseSocket($sSocket)
                        MsgBox(0, "提示", "   [" & $SendFile & "]这条信息发送完毕!   ");文字信息发送完毕提示信息接口
                EndIf
      EndIf
      If $sTCPListen <> -1 Then TCPCloseSocket($sTCPListen)
      TCPShutdown();停止UDP服务
EndFunc   ;==>_SendFileMsg#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_Icon=..\ico\2.ICO
#AutoIt3Wrapper_Outfile=..\1\TCP接收.exe
#AutoIt3Wrapper_Compression=4
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
;================================================
;本函数分为发送单元(_SendFileMsg)和接收单元(_ReceiveFileMsg),可同时发送(接收)文字信息或传送(接收)文件
;_SendFileMsg和_ReceiveFileMsg既可分开使用亦可合并到同一程序中协同使用
;提供诸多数据接口供主程序调用详见注释
;$rDownloads接收文件存放路径,默认为当前目录
;================================================
;#NoTrayIcon;不显示托盘图标
TCPStartup(); 开始 UDP 服务
Local $rTemer = 0, $rTCPListen = -1
While 1
      _ReceiveFileMsg()
WEnd

Func _ReceiveFileMsg($rDownloads = @DesktopCommonDir, $rPort = 8410);接收文件信息,可以更改默认端口号$rPort
      Local $rBuff, $rDays, $rFile, $rBytes = 0, $rPercent, $rAccept = -1, $rSocket = -1
      If StringRight($rDownloads, 1) <> "\" Then $rDownloads = $rDownloads & "\"
      If $rTemer = 0 Then
                $rTCPListen = TCPListen(@IPAddress1, $rPort); 创建一个已经连接的套接字绑定
                $rTemer = 1
      EndIf
      $rAccept = TCPAccept($rTCPListen)
      $rBuff = TCPRecv($rAccept, 2048, 1);接收信息
      If Not @error Then
                If $rAccept <> -1 Then TCPCloseSocket($rAccept)
                $rBuff = BinaryToString($rBuff, 4)
                If StringInStr($rBuff, "|||") Then;判断是文件传输
                        $rDays = StringSplit($rBuff, "|||", 1)
                        $rSocket = TCPConnect($rDays, $rPort);打开一个套接字连接到一个存在的服务器
                        ;弹出是否接收文件接口
                        $iMsgBoxAnswer = MsgBox(4 + 32, "文件传输", "是否接收: " & $rDays & " 传来的 " & $rDays & " 文件? " & Int($rDays / 1024 / 1024) & " (MB)   ")
                        Select
                              Case $iMsgBoxAnswer = 6;确定接收文件
                                        TCPSend($rSocket, "OK");发送同意接收文件信息
                                        $rFile = FileOpen($rDownloads & $rDays, 2 + 8 + 16);打开文件供写入
                                        Dim $ri = 0
                                        Do
                                                $rAccept = TCPAccept($rTCPListen)
                                        Until $rAccept <> -1
                                        While 1
                                                $rBuff = TCPRecv($rAccept, 1024 * 1024, 1);开始接收文件
                                                If Not @error Then
                                                      $ri += BinaryLen($rBuff);循环次数计数器
                                                      FileWrite($rFile, $rBuff);写入文件
                                                      $rPercent = $ri / $rDays * 100;已写入字节数百分比接口($rPercent)
                                                EndIf
                                                If $ri >= $rDays Then ExitLoop
                                        WEnd
                                        FileClose($rFile)
                                        If $rAccept <> -1 Then TCPCloseSocket($rAccept)
                                        If $ri >= $rDays Then;确认文件接收完毕接口
                                                MsgBox(0, "收到文件", "   " & $rDays & "文件" & Int($rDays / 1024 / 1024) & " (MB) 接收完毕!   ")
                                        EndIf
                              Case $iMsgBoxAnswer = 7;拒绝接收文件
                                        TCPSend($rSocket, "NO");发送拒绝接收文件信息
                        EndSelect
                If $rSocket <> -1 Then TCPCloseSocket($rSocket)
                Else;判断是信息传输
                        MsgBox(0, "收到消息:", $rBuff);这是收到的聊天信息接口
                EndIf
      EndIf
      Sleep(10)
EndFunc   ;==>_ReceiveFileMsg

Func OnAutoItExit()
      If $rTCPListen <> -1 Then TCPCloseSocket($rTCPListen)
      TCPShutdown()
EndFunc   ;==>OnAutoItExit

jycel 发表于 2009-12-30 14:50:14

可以的啊!外网需要公网IP,最好固定的IP!
还有就是存在映射端口问题!

871224 发表于 2009-12-30 15:14:49

回复 2# jycel


   额。。真的嘛? 难道我的实验出错了?
例如我外网是:xx.xx.xx.xx
内网中我的IP是10.246.133.155,可以与10.246.133.156通讯。
但是与其他外网IP如:yy.yy.yy.yy确通讯失败。接收端接收不到信息。哎。。。:face (2):

jycel 发表于 2009-12-30 15:23:02

本帖最后由 jycel 于 2009-12-30 15:24 编辑

交换数据都是用的外网地址:
在映射端口时就有外网地址和端口,对应的内网IP地址和端口
和你的外网交换也就相当于和你的内网映射的那个IP在交换!
你先试下外网聊天能成功了再弄发文件也就差不多了
我的网盘中,好像有这例子,截图就是用的那功能,发送图片再显示出来
http://jycel.ys168.com中

adasir 发表于 2010-6-7 22:09:04

标记下,学习了

lynfr8 发表于 2010-6-7 23:12:21

交换数据都是用的外网地址:
在映射端口时就有外网地址和端口,对应的内网IP地址和端口
和你的外网交换也 ...
jycel 发表于 2009-12-30 15:23 http://www.autoitx.com/images/common/back.gif

帮个小忙上代为上传了源码
页: [1]
查看完整版本: 利用TCP可以实现外网传输吗?