求用Winsock建立FTP客户端数据通道的示例(PORT方式)?

jinggangshi 2008-07-30 08:27:40
需求:
只用SOCKET(不用其他的包括异步套接字等),实现PORT方式建立数据通道,并用LIST命令取得文件列表。
求实现源码示例。

在网上搜了好多文章,讲述CSocket、CFTPConnect、....等许多种,CSocket及异步套接字实现的书及示例我都有,现在想用winsock的SOCKET做一个PORT方式的试验,试了好多种方法都不成功,请做过的朋友帮帮忙,我实在找不到了,在网上狂了一个多星期。
先行谢过诸位!
分不够以后再加。
...全文
164 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinggangshi 2008-08-20
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 gavin1203 的回复:]
vckbase上,由一个断点传续的例子,可以借鉴一下...
[/Quote]

谢谢!
还有没有更简单的例子?
gavin1203 2008-08-08
  • 打赏
  • 举报
回复
vckbase上,由一个断点传续的例子,可以借鉴一下...
jinggangshi 2008-08-08
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 stivenjia 的回复:]
我这里有PASV方式的
[/Quote]
谢谢,PASV我基本上能做好,现在就是想实现PORT,而且我的目标是在一个软件中嵌入一个FTP客户端,所以想自己用winsock写,还请多指教!
stivenjia 2008-08-08
  • 打赏
  • 举报
回复
我这里有PASV方式的
jinggangshi 2008-08-08
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 danscort2000 的回复:]
去找下开源的代码好了
大名鼎鼎的 wget 或者 curl 都可以,GPL的
[/Quote]
谢谢!我没有找到,有的是E文的网站上的,我看懂,能不能给个链接!
你说得很对,看别人的源码能学到好多东西,只是我还没有找到
jinggangshi 2008-08-08
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 danscort2000 的回复:]
如果你自己在内网中,但FTP服务器却在公网的话,除非你的网关做了某些端口的映射,否则用port命令基本失败.

这句话错了,具体原因TCP/IP协议卷里有解释的,事实上,在2000年以后,这个问题就已经在路由的OS层解决掉了,只要你线路上的路由设备是2000年后生产的[估计现在没2000年前的设备了吧],这不是个问题。
[/Quote]
谢谢!
我的FTP都在我的电脑上,Srev-U6
jinggangshi 2008-08-07
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 WinEggDrop 的回复:]
引用 10 楼 jinggangshi 的回复:
引用 8 楼 WinEggDrop 的回复:
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.


我现在动态绑定,检查端口被占用后重新绑定一个新端口,可是原来的端口总得要释放掉啊,我现在释放不掉。


反正用系统可用的端口,在绑定时用0端口,再调用getsockname()得到socket绑定的端口就是.至于端口不能释放,那是你自己代码的问题,已经离题了.
[/Quote]
你说离题也不全是,我要建立的是数据通道,应该是能够用的,现在只能说实现了链接,不能有效地使用,而且每次开一个新的端口并且不能有效释放,尽早会耗尽系统资源的啊,这不是一个合理的解决方法。
danscort2000 2008-08-07
  • 打赏
  • 举报
回复
如果你自己在内网中,但FTP服务器却在公网的话,除非你的网关做了某些端口的映射,否则用port命令基本失败.

这句话错了,具体原因TCP/IP协议卷里有解释的,事实上,在2000年以后,这个问题就已经在路由的OS层解决掉了,只要你线路上的路由设备是2000年后生产的[估计现在没2000年前的设备了吧],这不是个问题。
danscort2000 2008-08-07
  • 打赏
  • 举报
回复
去找下开源的代码好了
大名鼎鼎的 wget 或者 curl 都可以,GPL的
WinEggDrop 2008-08-07
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jinggangshi 的回复:]
引用 11 楼 WinEggDrop 的回复:
引用 10 楼 jinggangshi 的回复:
引用 8 楼 WinEggDrop 的回复:
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.


我现在动态绑定,检查端口被占用后重新绑定一个新端口,可是原来的端口总得要释放掉啊,我现在释放不掉。


反正用系统可用的端口,在绑定时用0端口,再调用getsockname()得到socket绑定的端口就是.至于端口不能释放,那…
[/Quote]

这个贴子只是去讨论"如何建立PORT模式的FTP数据通道".既然数据通道已经能建立了,那就是完成了,至于说资源不能有效释放,如果方法是正确的,你不能释放资源,那明显就是你的代码问题,或代码逻辑上问题.这里只是讨论方法,没人能教你如何写代码.
jinggangshi 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 WinEggDrop 的回复:]
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.
[/Quote]
是的,是一个端口。
这个程序是我的一个试验,就是试验一个同端口(最初的想法还是同一个连接)多次使用的问题。
正如你所说的,端口好象没有释放好,我找了许多关于SOCKET释放的资料,没有找到立即释放的方法。
也许这是一个思路的错误,可能绑定同一个端口的做法是不能成功的。
下一步的试验就是绑定动态端口,设想绑定不成功就根据返回错误信息再重建SOCKET,也就是上面所说的ACCEPT包含的三个步骤。
还请多多指教!
WinEggDrop 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jinggangshi 的回复:]
引用 8 楼 WinEggDrop 的回复:
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.


我现在动态绑定,检查端口被占用后重新绑定一个新端口,可是原来的端口总得要释放掉啊,我现在释放不掉。
[/Quote]

反正用系统可用的端口,在绑定时用0端口,再调用getsockname()得到socket绑定的端口就是.至于端口不能释放,那是你自己代码的问题,已经离题了.
jinggangshi 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 WinEggDrop 的回复:]
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.
[/Quote]

我现在动态绑定,检查端口被占用后重新绑定一个新端口,可是原来的端口总得要释放掉啊,我现在释放不掉。
jinggangshi 2008-08-01
  • 打赏
  • 举报
回复
现在PORT模式的数据通道能建立,也能用LIST获取文件列表,但存在一个问题,按下面的流程设计,运行 一次后,第二次就不能成功取得数据。

USER=>PASS=>TYPE=>ACCEPT=>PORT=>LIST=>RECV。(这功能都对应一个BUTTON)

运行程序第一次能取得文件列表,第二次就不行,在ACCEPT这个环节中,ACCEPT包括(bind;listen;accept)三个环节,这三个环节都会出错。
其中bind()的问题可以通过close(sock)关掉重来来解决;解决了bind()后listen也就没有问题。
但是accept确好解决,会出错的类型有几个:主要是WSAEINTR(10004L)、WSAEINVAL(10022L).
现在我按下面流程执行:
USER=>PASS=>TYPE=>ACCEPT=>PORT=>LIST=>RECV=>close(SOCK);第一次成功(肯定)
USER=>PASS=>TYPE=>ACCEPT=>PORT=>LIST=>RECV=>close(SOCK);第二次不成功(肯定)
USER=>PASS=>TYPE=>ACCEPT=>PORT=>LIST=>RECV=>close(SOCK);第三次成功
USER=>PASS=>TYPE=>ACCEPT=>PORT=>LIST=>RECV=>close(SOCK);第四次不成功

一般隔一次成功一次;
若时间间隔长,可能都能成功;
中间隔一次PASV方式的话,每次都能成功。

环境:客户端、服务器都在本机,Serv-U6,XP-SP3,vs2005
WinEggDrop 2008-08-01
  • 打赏
  • 举报
回复
你是不是绑死在同一个端口呀,如果是,有可能是因为那个端口还没释放好,又想绑入,绑不入是不奇怪的.
jinggangshi 2008-08-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 WinEggDrop 的回复:]
1.你说在自己电脑上验证,但没说FTP服务器也是你自己本机装呢.
2.你bind()后,得到绑定的端口和本机IP,发送了Port命令再执行accept()呀.
[/Quote]

那你的LIST命令又怎么下呢?
WinEggDrop 2008-07-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jinggangshi 的回复:]
引用 3 楼 WinEggDrop 的回复:

如果使用的是一个连接处理一个客户方式的话,是不需要再新建一个新的线程处理.我是怀疑你是不是在内网的原因,自己找个flashfxp,设置使用port模式,连上FTP服务器测试就清楚.如果flashfxp也因为你是内网不能成功列出数据,那明显是你自己的环境造成的.

兄弟,都说了是在我自己的电脑上,还会是外网,FTP就在我的本本上!!!!!!!!!!!
???? 不需要再新建一个新的线程处理????…
[/Quote]

1.你说在自己电脑上验证,但没说FTP服务器也是你自己本机装呢.
2.你bind()后,得到绑定的端口和本机IP,发送了Port命令再执行accept()呀.

jinggangshi 2008-07-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 WinEggDrop 的回复:]

如果使用的是一个连接处理一个客户方式的话,是不需要再新建一个新的线程处理.我是怀疑你是不是在内网的原因,自己找个flashfxp,设置使用port模式,连上FTP服务器测试就清楚.如果flashfxp也因为你是内网不能成功列出数据,那明显是你自己的环境造成的.
[/Quote]
兄弟,都说了是在我自己的电脑上,还会是外网,FTP就在我的本本上!!!!!!!!!!!
???? 不需要再新建一个新的线程处理??????
当系统执行到accept时 ,应该就是停在那儿了吧,那你怎样发送PORT命令啊?
兄弟,我要求只用winsock的SOCKET........
WinEggDrop 2008-07-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jinggangshi 的回复:]
引用 1 楼 WinEggDrop 的回复:
如果你自己在内网中,但FTP服务器却在公网的话,除非你的网关做了某些端口的映射,否则用port命令基本失败.

代码没有,我只是说下流程.
1.本地绑定一个端口,具体是什么端口,自己用getpeername什么的得到.
2.拿到本地IP
3.将IP和端口转换,然后用Port命令发送过去服务器
4.发送LIST命令


这些我都试过了,具体细节实现不了,Port后数据通道的套接字在什么时候accept,因为会阻塞,那么…
[/Quote]

如果使用的是一个连接处理一个客户方式的话,是不需要再新建一个新的线程处理.我是怀疑你是不是在内网的原因,自己找个flashfxp,设置使用port模式,连上FTP服务器测试就清楚.如果flashfxp也因为你是内网不能成功列出数据,那明显是你自己的环境造成的.
jinggangshi 2008-07-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 WinEggDrop 的回复:]
如果你自己在内网中,但FTP服务器却在公网的话,除非你的网关做了某些端口的映射,否则用port命令基本失败.

代码没有,我只是说下流程.
1.本地绑定一个端口,具体是什么端口,自己用getpeername什么的得到.
2.拿到本地IP
3.将IP和端口转换,然后用Port命令发送过去服务器
4.发送LIST命令
[/Quote]

这些我都试过了,具体细节实现不了,Port后数据通道的套接字在什么时候accept,因为会阻塞,那么就要用新的线程,新线程中建立的套接字的数据怎么读取,是用指针吗?

我在自己的电脑上试验
加载更多回复(1)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧