找回密码
 加入
搜索
查看: 4895|回复: 5

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

  [复制链接]
发表于 2009-12-30 10:04:07 | 显示全部楼层 |阅读模式
如下是论坛中找到的源码,局域网传输经实践可行。但是外网就不行了。
#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[1], $rPort);打开一个套接字连接到一个存在的服务器
                        ;弹出是否接收文件接口
                        $iMsgBoxAnswer = MsgBox(4 + 32, "文件传输", "是否接收: " & $rDays[1] & " 传来的 " & $rDays[2] & " 文件? " & Int($rDays[3] / 1024 / 1024) & " (MB)   ")
                        Select
                                Case $iMsgBoxAnswer = 6;确定接收文件
                                        TCPSend($rSocket, "OK");发送同意接收文件信息
                                        $rFile = FileOpen($rDownloads & $rDays[2], 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[3] * 100;已写入字节数百分比接口($rPercent)
                                                EndIf
                                                If $ri >= $rDays[3] Then ExitLoop
                                        WEnd
                                        FileClose($rFile)
                                        If $rAccept <> -1 Then TCPCloseSocket($rAccept)
                                        If $ri >= $rDays[3] Then;确认文件接收完毕接口
                                                MsgBox(0, "收到文件", "   " & $rDays[2] & "文件" & Int($rDays[3] / 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
发表于 2009-12-30 14:50:14 | 显示全部楼层
可以的啊!外网需要公网IP,最好固定的IP!
还有就是存在映射端口问题!
 楼主| 发表于 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确通讯失败。接收端接收不到信息。哎。。。
发表于 2009-12-30 15:23:02 | 显示全部楼层
本帖最后由 jycel 于 2009-12-30 15:24 编辑

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

评分

参与人数 1贡献 +1 收起 理由
lynfr8 + 1

查看全部评分

发表于 2010-6-7 22:09:04 | 显示全部楼层
标记下,学习了
发表于 2010-6-7 23:12:21 | 显示全部楼层
交换数据都是用的外网地址:
在映射端口时就有外网地址和端口,对应的内网IP地址和端口
和你的外网交换也 ...
jycel 发表于 2009-12-30 15:23


帮个小忙上代为上传了源码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-11-16 00:34 , Processed in 0.123978 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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