ftp port方式编程求助

happyzhang 2007-04-26 12:57:02
今天遇到一个奇怪的问题,在调试一ftp port方式的client端程序,第一次数据通道连接成功,传送数据也正常。完成本次操作,关闭数据连接,接着又进行第二次数据连接,却发现client端在accept()函数处堵住。两次侦听的是同一个端口,怀疑是前一次的连接没有释放,端口还是被占用,可是用netstat 看了一下我侦听的那个端口,是没有连接的,怎么第二次建立数据连接就堵住了呢?还请高手指点啊,最有可能哪里出问题了呢?
...全文
272 7 打赏 收藏 转发到动态 举报
写回复
用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!

23,114

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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