社区
Linux/Unix社区
帖子详情
ftp port方式编程求助
happyzhang
2007-04-26 12:57:02
今天遇到一个奇怪的问题,在调试一ftp port方式的client端程序,第一次数据通道连接成功,传送数据也正常。完成本次操作,关闭数据连接,接着又进行第二次数据连接,却发现client端在accept()函数处堵住。两次侦听的是同一个端口,怀疑是前一次的连接没有释放,端口还是被占用,可是用netstat 看了一下我侦听的那个端口,是没有连接的,怎么第二次建立数据连接就堵住了呢?还请高手指点啊,最有可能哪里出问题了呢?
...全文
291
7
打赏
收藏
ftp port方式编程求助
今天遇到一个奇怪的问题,在调试一ftp port方式的client端程序,第一次数据通道连接成功,传送数据也正常。完成本次操作,关闭数据连接,接着又进行第二次数据连接,却发现client端在accept()函数处堵住。两次侦听的是同一个端口,怀疑是前一次的连接没有释放,端口还是被占用,可是用netstat 看了一下我侦听的那个端口,是没有连接的,怎么第二次建立数据连接就堵住了呢?还请高手指点啊,最有可能哪里出问题了呢?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
mymtom
2007-07-18
打赏
举报
回复
这个不是Linux下的代码,是Windows下的。
第二个问题是C++的基本概念,随便找本书都有,看看这个:
http://www.pconline.com.cn/pcjob/process/other/others/0407/423693.html
yandw
2007-07-17
打赏
举报
回复
to mymtom 老兄:
using namespace std;
这句是什么意思呀,
到那里 STD?
#include <winsock.h>?,这不是LINUX下的代码吗?怎么还要这个?
mymtom
2007-04-27
打赏
举报
回复
试试下面的程序!
#include <string>
#include <iostream>
using namespace std;
#include <winsock.h>
#define HOST "host.domain.com"
#define USER "user"
#define PASS "password"
#define CRLF "\r\n"
#define CR "\r"
#define LF "\n"
#define MAX_RECV_LEN 40960
#define SA struct sockaddr
typedef int socklen_t;
int main()
{
SOCKET sockfd, listenfd, datafd;
WSADATA wsaData;
struct sockaddr_in server_addr, data_addr, listen_name;
socklen_t data_addrlen, listen_namelen;
struct hostent *hp;
string strSend;
string strRecv;
char bufRecv[MAX_RECV_LEN + 1];
int nSend, nRecv, nRet;
struct timeval tm;
fd_set readfds;
// Initialize
if (WSAStartup(MAKEWORD(2,1),&wsaData)!=0)
{
WSACleanup();
exit(1);
}
if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
exit(1);
}
hp=gethostbyname(HOST);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(21);
memcpy((char*)&server_addr.sin_addr,(char*)hp->h_addr,hp->h_length);
if( connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) <0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
strSend = "USER " USER CRLF;
if( (nSend = send(sockfd, strSend.c_str(), strSend.length() ,0)) <0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
strSend = "PASS " PASS CRLF;
if( (nSend = send(sockfd, strSend.c_str(), strSend.length() ,0)) <0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
// Listen socket
if ( (listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
exit(1);
}
listen_namelen = sizeof(listen_name);
memset(&listen_name, 0, listen_namelen);
listen_name.sin_addr.s_addr = INADDR_ANY;
listen_name.sin_family = AF_INET;
listen_name.sin_port = 0;
if (bind(listenfd, (SA *)&listen_name, listen_namelen) < 0)
{
nRet = WSAGetLastError();
exit(1);
}
if ( (nRet = listen(listenfd, 1)) < 0)
{
exit(1);
}
getsockname(listenfd, (SA *)&listen_name, &listen_namelen);
sprintf(bufRecv, "%d,%d", ntohs( listen_name.sin_port) / 256, ntohs(listen_name.sin_port) % 256);
strSend = string("PORT 153,58,244,113,") + bufRecv + CRLF;
if( (nSend = send(sockfd, strSend.c_str(), strSend.length() ,0)) < 0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
strSend = string("LIST") + CRLF;
if( (nSend = send(sockfd, strSend.c_str(), strSend.length() ,0)) < 0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
data_addrlen = sizeof(data_addr);
memset(&data_addr, 0, data_addrlen);
if ( (datafd = accept(listenfd, (SA *)&data_addr, &data_addrlen)) < 0 )
{
exit(1);
}
bufRecv[0] = '\0';
if ( (nRecv = recv(datafd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
closesocket(datafd);
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
tm.tv_sec = 0;
tm.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
nRet = select(sockfd + 1, &readfds, NULL, NULL, &tm);
if ( nRet > 0)
{
if (FD_ISSET(sockfd, &readfds))
{
bufRecv[0] = '\0';
if ( (nRecv = recv(sockfd, bufRecv, MAX_RECV_LEN, 0)) < 0 )
{
exit(1);
}
bufRecv[nRecv] = '\0';
strRecv = bufRecv;
cout << strRecv;
}
}
closesocket(listenfd);
closesocket(sockfd);
WSACleanup();
return 0;
}
mymtom
2007-04-27
打赏
举报
回复
贴代码!
happyzhang
2007-04-27
打赏
举报
回复
这个问题找到原因了,关闭一个socket连接总是会处于time_wait状态一段时间,其实连接还并没有释放,这样我的程序又去马上复用这个端口,这样就挂住了。感谢mymtom() 的热心解答。
happyzhang
2007-04-26
打赏
举报
回复
我是每次数据连接之前都会发port命令的,今天又调了一天还是没有进展,好郁闷啊。
mymtom
2007-04-26
打赏
举报
回复
我很久没有写类似的程序了!你试试每次数据连接之前都发送一下PORT命令是否可以!
因为在我隐约记得很久以前用CutFTP时,每次LIST之前都有PORT!
VC++实现
FTP
编程
本文详细介绍了如何使用VC++的WinInet API实现
FTP
编程
,包括连接
FTP
服务器、创建删除目录、上传下载删除文件。通过具体示例展示了如何在VC++中创建CInternetSession和C
Ftp
Connection对象,以及如何进行
FTP
会话和文件操作。文章最后讨论了
FTP
Transfer类的封装,提供了一种更方便的
FTP
操作
方式
。
FTP
协议
编程
看这一篇文章就够了
本文深入解析
FTP
协议的工作原理,包括主动模式和被动模式的数据传输过程,以及如何使用socket
编程
实现
FTP
文件下载功能。通过实际代码示例,读者可以学习如何在RTthread操作系统上编写
FTP
客户端。
FTP
协议进行连接的两种
方式
本文详细介绍了
FTP
协议的两种连接
方式
:
PORT
(主动
方式
)和PASV(被动
方式
),并解释了每种
方式
的工作原理及如何在
编程
时选择合适的方法。
FTP
API
编程
本文介绍了使用WinINet API进行
FTP
操作的基本流程,包括InternetOpen和InternetConnect函数的使用方法,以及如何创建和关闭
FTP
会话。
Ftp
客户端
编程
本文围绕
FTP
展开,介绍了
FTP
协议目标,指出Windows里
Ftp
客户端命令并非真正的
Ftp
命令,真正的
Ftp
命令应参考RFC959文档。还阐述了
Ftp
命令的返回值及获取端口号的方法,最后说明了
Ftp
客户端
编程
结构及操作流程。
Linux/Unix社区
23,223
社区成员
74,536
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章