(200分求救)用socket API获取FTP服务器文件列表

Stefine 2006-09-21 01:17:21
至于如何获取大家都清楚,发送几个命令(主动 PORT LIST 与被动方式 PASV)

我仅用主动模式获取服务器的返回列表信息
参考了下别人源代码,用MFC封装类写的
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:BOOL CFTPClient::List ()
//
// 描述:
// 列出当前文件信息,在下面函数里对信息进行了解析(就是分析字符串啦)
//
// 参数:
// -无

// 返回:
// -BOOL 成功返回 TRUE 否则返回 FALSE
//
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::List ()
{

CSocket sServ;//用于侦听
CAsyncSocket asDataChannel; //用于接收数据
CString strCommand;//发送的命令
CString strAdress;//本机地址
UINT nListenPort ; //侦听的端口号

//开始侦听 这个要在发送命令之前,否则出错
if (!(sServ.Create (0,SOCK_STREAM,NULL))||(!sServ.Listen ()))
{
return FALSE;
}

sServ.GetSockName(strAdress,nListenPort);
UINT temp;
//在连接时设置了用户的IP,因此要从这里得到你现在作用的IP地址,而不要从注释的方式得到
//sServ.GetSockName(strAdress,nListenPort);
this->m_pSocket->GetSockName (strAdress,temp);


/******这里是(主动模式)发送PORT, TYPE I, LIST命令给服务器*****/


//接受服务器的联接
if (!sServ.Accept (asDataChannel ))
return FALSE;

DWORD lpArgument = 0;
int num,sum;
//定义缓冲区的大小'
const int BUFSIZE = 4096;
//清空缓冲区
this->m_btBuf.RemoveAll ();
this->m_btBuf.SetSize (BUFSIZE);

//获取数据
if ((!asDataChannel.AsyncSelect (0))||(!asDataChannel.IOCtl (FIONBIO,&lpArgument)))
{
return FALSE;
}

//获取数据
sum = 0;
while (1)//在这里没有循环结束条件
{
TRY
{
if (!(num = asDataChannel.Receive (this->m_btBuf.GetData() + sum,BUFSIZE,0)||(num == SOCKET_ERROR)))
break;

//sleep(0);
sum += num;
this->m_btBuf.SetSize (sum+BUFSIZE);
}
CATCH(CException,e)
{
return FALSE;
}
END_CATCH
}
asDataChannel.Close ();
::AfxMessageBox(CString((LPCTSTR)this->m_btBuf.GetData()));
}
他的代码很好懂(CAsyncSocket是不堵塞的,所以他可以一直就这样用是吧)
下面我模仿着他的代码自己用SOCKET API写了下:
下面是我的代码:

...全文
410 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Stefine 2006-09-29
  • 打赏
  • 举报
回复
谢谢你
只是我为什么这样还是无法达到要求咧?

由于这个是阻塞的,不方便调试,但是还没正确返回结果(列表)
softrain 2006-09-28
  • 打赏
  • 举报
回复
我有一疑问:你在connect线程里建立一个g_socketClient,好像在另外的地方不要用到他啊?

我先在accept时等待客户来连接,然后connect启动,通过第二个参数SOCKADDR指定目的信息(与服务器端口相同),连接上后socketConn返回,通过这个就接收服务器返回的列表信息

再帮我看看,THX了


楼主对client和server弄混淆了。
如果你是要FTP下载,那么你是client,如果是提供FTP下载,那么你是server.
server的处理是这样的:创建监听套接字:listen ,accept出一个新的socket连接,用这个新的socket接受client发送的请求并回应请求;
client的处理是这样的:创建套接字,connect 到server地址,成功后,就可以用这个socket发送请求消息了。
你上面的这个例子是对的。
Stefine 2006-09-23
  • 打赏
  • 举报
回复
TO: softrain(曾经的月光,现在的日光)

要不我把工程传你,你帮我看看,我QQ 276244858

谢谢
Stefine 2006-09-23
  • 打赏
  • 举报
回复
其实我的问题很明确:
就是获取FTP服务器文件列表,更简单的说,就是将下面这段代码以socket API翻译过来

//列出文件列表
BOOL CFTPCommandProcessor::List()
{
CString lhost,temp,rhost;
UINT localsock,i;
CFile datafile;
CSocket sockSrvr;
CAsyncSocket datachannel;
int num, sum;
const int BUFSIZE = 4096;
DWORD lpArgument=0;

m_buf.RemoveAll();
m_buf.SetSize(BUFSIZE);
if(!FTPcommand("TYPE I"))
return FALSE; // 请求二进制模式

m_retmsg.LoadString(IDS_FTPMSG6);
// 获取本地IP地址
if(!m_Ctrlsok->GetSockName(lhost,localsock))
return FALSE;;
while(1) {
// 将点转化成逗号
if((i=lhost.Find("."))==-1) break;
lhost.SetAt(i,',');
}
if((!sockSrvr.Create(0, SOCK_STREAM, NULL))
|| (!sockSrvr.Listen()))
return FALSE;
if(!sockSrvr.GetSockName(temp,localsock))
return FALSE;
lhost.Format(lhost+",%d,%d", localsock / 256, localsock % 256);
if(!FTPcommand("PORT "+lhost))
return FALSE;

if(!WriteStr("LIST") )
return FALSE;
if(!ReadStr())
return FALSE;
if(!sockSrvr.Accept(datachannel))
return FALSE;
if((!datachannel.AsyncSelect(0)) ||
(!datachannel.IOCtl(FIONBIO,&lpArgument))) {
m_retmsg.LoadString(IDS_FTPMSG6);
return FALSE;
}
sum = 0;
while(1) { // 获得数据
TRY {
if(!(num = datachannel.Receive(m_buf.GetData() + sum, BUFSIZE, 0))
|| num == SOCKET_ERROR)
break;
TRACE("Received :%d\n", num);
Sleep(0);
sum += num;
m_buf.SetSize(sum + BUFSIZE);
}
CATCH (CException,e) {
m_retmsg.LoadString(IDS_FTPMSG5);
return FALSE;
}
END_CATCH
}
datachannel.Close();
}

再次恳求路过的仁兄们help下
Stefine 2006-09-23
  • 打赏
  • 举报
回复
再次感谢softrain(曾经的月光,现在的日光)
不过你说的这样,我早测试过了
你看下面代码:

SOCKET g_socketServ, g_socketClient;
HANDLE g_hAcceptEvent;
HANDLE g_hConnectEvent;
HANDLE g_hRecvEvent;
SOCKADDR_IN addrSock;
int len = sizeof( addrSock );
CByteArray btBuf;

void CMultiThreadFtpConnect::GetFtpServerList()
{
/*****发送TYPE I 命令给服务器******/

//创建一服务器socket,绑定端口并监听
g_socketServ = socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET == g_socketServ )
{
AfxMessageBox( _T("套接字创建失败或者监听失败!") );
return ;
}

static int port = 7000;
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(++port);
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

int retval;
retval=bind( g_socketServ ,(SOCKADDR*)&addrSock, sizeof(SOCKADDR) );
if(SOCKET_ERROR==retval)
{
closesocket( g_socketServ );
AfxMessageBox( _T("在要获取服务器文件列表时,绑定端口失败,请检查端

口是否已经在用!") );
return ;
}

if( listen( g_socketServ, SOMAXCONN ) != 0 )
{
strMsg.Format( _T("listen错误,错误代号:%d"),WSAGetLastError() );
AfxMessageBox( strMsg );
return;
}

/**********发送PORT 与 LIST命令************/

//服务器等待连接(accept)线程
g_hAcceptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hAcceptEvent );

HANDLE hAcceptThread;
hAcceptThread = CreateThread( NULL, 0, AcceptThreadPorc, NULL, 0, NULL);
CloseHandle( hAcceptThread );

//客户端主动连接(connect)线程
g_hConnectEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hConnectEvent );

HANDLE hConnectThread;
hConnectThread = CreateThread( NULL, 0, ConnectThreadPorc, NULL, 0, NULL);
CloseHandle( hConnectThread );

}



DWORD WINAPI AcceptThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hAcceptEvent, INFINITE );

SOCKET socketConn;
while(1)
{
CString strMsg;
socketConn = accept( g_socketServ, (SOCKADDR*)&addrSock, &len);
if( INVALID_SOCKET == socketConn )
{
strMsg.Format( _T("accept线程错误,错误代号:%d"),WSAGetLastError()

);
AfxMessageBox( strMsg );
return 0;
}
}

/*****连接建立,接收数据***/

DWORD lpArgument = 0;
int num,sum;
//定义缓冲区的大小
const int BUFSIZE = 4096;
//清空缓冲区
btBuf.RemoveAll ();
btBuf.SetSize (BUFSIZE);

//接收数据
if( !ioctlsocket( socketConn, FIONBIO, &lpArgument) )
return 0;

//获取数据
sum = 0;
while (1)//在这里没有循环结束条件
{
TRY
{
if (!(num = recv( socketConn, (LPTSTR)btBuf.GetData() + sum,

BUFSIZE,0 )||(num == SOCKET_ERROR)))
break;

//sleep(0);
sum += num;
btBuf.SetSize(sum+BUFSIZE);
}
CATCH(CException,e)
{
return 0;
}
END_CATCH
}
closesocket( socketConn );
AfxMessageBox( (LPTSTR)btBuf.GetData() );

CloseHandle( g_hAcceptEvent );
return 0;

}

DWORD WINAPI ConnectThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hConnectEvent, INFINITE );

SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr(_T("127.0.0.1") );
addrClient.sin_family = AF_INET;
addrClient.sin_port = addrSock.sin_port;
int lenClient = sizeof( addrClient );

connect( g_socketClient, (SOCKADDR*)&addrClient, lenClient );

CloseHandle( g_hConnectEvent );

return 0;
}
我有一疑问:你在connect线程里建立一个g_socketClient,好像在另外的地方不要用到他啊?

我先在accept时等待客户来连接,然后connect启动,通过第二个参数SOCKADDR指定目的信息(与服务器端口相同),连接上后socketConn返回,通过这个就接收服务器返回的列表信息

再帮我看看,THX了
softrain 2006-09-23
  • 打赏
  • 举报
回复
你下面的代码才是对的。
但是你的代码里怎么能有accept( g_Client,...这样的错误调用呢!!!
softrain 2006-09-23
  • 打赏
  • 举报
回复
这样得到的一自己的用来连接的socket做什么啊,再在AcceptThreadProc线程函数里accept时
socketConn = accept( g_Client, (SOCKADDR*)&addrSock, &len);吗?
不行啊?
////////////////////////
这句改为:
socketConn = accept( g_socketServ, (SOCKADDR*)&addrSock, &len);吗?
其他不变
Stefine 2006-09-22
  • 打赏
  • 举报
回复
照我自己的理解:如下面这段普通的TCP发送接收程序

客户端代码:
//初始化略
SOCKET socketClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSever;
addrSever.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSever.sin_family=AF_INET;
addrSever.sin_port=htons(6000);

connect(socketClient,(SOCKADDR*)&addrSever,sizeof(SOCKADDR));

//下面是接收与发送

服务器代码:
SOCKET socketSever=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSever;
addrSever.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSever.sin_family=AF_INET;
addrSever.sin_port=htons(6000);

bind(socketSever,(SOCKADDR*)&addrSever,sizeof(SOCKADDR));

listen(socketSever,9);

SOCKADDR_IN addrClient;
int len=sizeof(addrClient);

while(1)
{
SOCKET sockConn=accept(socketSever,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome to %s to my web !",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];
recv(sockConn,recvBuf,strlen(recvBuf)+1,0);
printf("%s\n",recvBuf);
closesocket(sockConn);
// WSACleanup( );
}

这样就很好理解啊,
先启动服务器端,服务器端启动后一直等待有客户端来连接(因为accept是同步(堵塞)的, accept前必须对其绑定端口与监听)
再启动客户端,此时就去连接服务端(其port相同),此时服务器端accept正确返回,使其正确得到sockConn的值,服务端便可通过这个send与recv了

这过程没错吧?
我实现时就是按照这样的!
哪位大哥能再指点啊,小弟实在没辙了,欢迎大家提出建议与看法,或提供参考资料,不尽感谢啊

Stefine 2006-09-22
  • 打赏
  • 举报
回复
TO softrain(曾经的月光,现在的日光)
SOCKET g_client;
DWORD WINAPI ConnectThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hConnectEvent, INFINITE );

SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr(_T("127.0.0.1") );
addrClient.sin_family = AF_INET;
addrClient.sin_port = addrSock.sin_port;
int lenClient = sizeof( addrClient );
g_client= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
connect( g_client, (SOCKADDR*)&addrClient, lenClient );

CloseHandle( g_hConnectEvent );
//此处可以发送请求并接收返回数据了
return 0;
}

这样得到的一自己的用来连接的socket做什么啊,再在AcceptThreadProc线程函数里accept时
socketConn = accept( g_Client, (SOCKADDR*)&addrSock, &len);吗?
不行啊?

trueadou 2006-09-22
  • 打赏
  • 举报
回复
up
VCSQLVB 2006-09-22
  • 打赏
  • 举报
回复
看看FTP资料吧,说得很清楚.
Stefine 2006-09-22
  • 打赏
  • 举报
回复
to VCSQLVB(深谷清音(谁知还是难脱俗尘))

FTP资料大都上面也只说了一些FTP命令及其说明吧?如果你有能告诉下我不咯?谢谢
wyfcat 2006-09-22
  • 打赏
  • 举报
回复
up
softrain 2006-09-21
  • 打赏
  • 举报
回复
ConnectThreadPorc中你建立连接要用 g_socketConn,只要服务器线程才要用g_socketServ.
另外连接和接收线程最好用同一个,否则连接不成功的时候recv操作必然失败.
另外event对象不能马上CloseHandle.
问题多多啊.
DentistryDoctor 2006-09-21
  • 打赏
  • 举报
回复
g_hAcceptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hAcceptEvent );
CloseHandle( g_hAcceptEvent );

g_hConnectEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hConnectEvent );
CloseHandle( g_hConnectEvent );

g_hRecvEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hRecvEvent );
CloseHandle( g_hRecvEvent );


这些代码写有CreateThread之后,有什么作用呢?并用SetEvent之后马上CloseHandle了.

线程间都在访问全局的g_socketConn, ?

connect( g_socketServ, (SOCKADDR*)&addrClient, lenClient ); ???
g_socketServ????
softrain 2006-09-21
  • 打赏
  • 举报
回复
connect函数你没理解对.
connect是为自己要用的套接字建立连接,连接的目的信息在connect的第二个参数里,第一个参数是要用来建立连接的套接字.
softrain 2006-09-21
  • 打赏
  • 举报
回复
accept是阻塞的.
都跟你说了connect线程要操作的SOCKET不是socketServ,而是自己的一个SOCKET.
你这样改accept就可以返回了:
声明全局变量
SOCKET g_client;
DWORD WINAPI ConnectThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hConnectEvent, INFINITE );

SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr(_T("127.0.0.1") );
addrClient.sin_family = AF_INET;
addrClient.sin_port = addrSock.sin_port;
int lenClient = sizeof( addrClient );
g_client= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
connect( g_client, (SOCKADDR*)&addrClient, lenClient );

CloseHandle( g_hConnectEvent );
//此处可以发送请求并接收返回数据了
return 0;
}
Stefine 2006-09-21
  • 打赏
  • 举报
回复
//此为全局变量
SOCKET g_socketServ, g_socketConn;
HANDLE g_hAcceptEvent;
HANDLE g_hConnectEvent;
HANDLE g_hRecvEvent;
SOCKADDR_IN addrSock;
int len = sizeof( addrSock );
CByteArray btBuf;

void CMultiThreadFtpConnect::GetFtpServerList()
{
CString strCommand, strMsg;

//绑定端口
g_socketServ = socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET == g_socketServ )
{
AfxMessageBox( _T("套接字创建失败或者监听失败!") );
return ;
}

static int port = 7000;
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(++port);
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

int retval;
retval=bind( g_socketServ ,(SOCKADDR*)&addrSock, sizeof(SOCKADDR) );
if(SOCKET_ERROR==retval)
{
closesocket( g_socketServ );
AfxMessageBox( _T("在要获取服务器文件列表时,绑定端口失败,请检查端口是否已经在用!") );
return ;
}

if( listen( g_socketServ, SOMAXCONN ) != 0 )
{
strMsg.Format( _T("listen错误,错误代号:%d"),WSAGetLastError() );
AfxMessageBox( strMsg );
return;
}

/************发送命令PORT TYPE I LIST给服务器,并接受返回************/

//分别创建三个线程用来处理 服务器等待连接(accept),客户端主动连接(connect)

HANDLE hAcceptThread, hConnectThread, hRecvThread;
hAcceptThread = CreateThread( NULL, 0, AcceptThreadPorc, NULL, 0, NULL);
hConnectThread = CreateThread( NULL, 0, ConnectThreadPorc, NULL, 0, NULL);
hRecvThread = CreateThread( NULL, 0, RecvThreadProc, NULL, 0, NULL);
CloseHandle( hAcceptThread );
CloseHandle( hConnectThread );
CloseHandle( hRecvThread );

g_hAcceptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hAcceptEvent );
CloseHandle( g_hAcceptEvent );

g_hConnectEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hConnectEvent );
CloseHandle( g_hConnectEvent );

g_hRecvEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hRecvEvent );
CloseHandle( g_hRecvEvent );

}


DWORD WINAPI AcceptThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hAcceptEvent, INFINITE );

while(1)
{
CString strMsg;
g_socketConn = accept( g_socketServ, (SOCKADDR*)&addrSock, &len);
if( INVALID_SOCKET == g_socketConn )
{
strMsg.Format( _T("accept线程错误,错误代号:%d"),WSAGetLastError()

);
AfxMessageBox( strMsg );
return 0;
}
}
return 0;
}

DWORD WINAPI ConnectThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hConnectEvent, INFINITE );

SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr(_T("127.0.0.1") );
addrClient.sin_family = AF_INET;
addrClient.sin_port = addrSock.sin_port;
int lenClient = sizeof( addrClient );

connect( g_socketServ, (SOCKADDR*)&addrClient, lenClient );

return 0;
}

DWORD WINAPI RecvThreadProc( LPVOID lpParameter )
{
WaitForSingleObject( g_hRecvEvent, INFINITE );

DWORD lpArgument = 0;
int num,sum;
//定义缓冲区的大小'
const int BUFSIZE = 4096;
//清空缓冲区
btBuf.RemoveAll ();
btBuf.SetSize (BUFSIZE);

//接收数据
if( !ioctlsocket( g_socketConn, FIONBIO, &lpArgument) )
return 0;

//获取数据
sum = 0;
while (1)//在这里没有循环结束条件
{
TRY
{
if (!(num = recv( g_socketConn, (LPTSTR)btBuf.GetData() + sum,

BUFSIZE,0 )||(num == SOCKET_ERROR)))
break;

//sleep(0);
sum += num;
btBuf.SetSize(sum+BUFSIZE);
}
CATCH(CException,e)
{
return 0;
}
END_CATCH
}
closesocket( g_socketConn );
AfxMessageBox( (LPTSTR)btBuf.GetData() );
return 0;
}

现在这样子那个接受服务器端accept的g_socketConn还是不能得到正确的值,始终为0
麻烦各们大虾们指点一二,小弟初涉网络编程...
不尽感激
分is not problem
呵呵
Stefine 2006-09-21
  • 打赏
  • 举报
回复
先谢谢牙医和楼上的这位,参照你们的意见,我现在改成这样

//全局变量
SOCKET g_socketServ;
HANDLE g_hAcceptEvent;
HANDLE g_hConnectEvent;
SOCKADDR_IN addrSock;
int len = sizeof( addrSock );
CByteArray btBuf;

void CMultiThreadFtpConnect::GetFtpServerList()
{


CString strCommand, strMsg;

//绑定端口

g_socketServ = socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET == g_socketServ )
{
AfxMessageBox( _T("套接字创建失败或者监听失败!") );
return ;
}

static int port = 7000;
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(++port);
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

int retval;
retval=bind( g_socketServ ,(SOCKADDR*)&addrSock, sizeof(SOCKADDR) );
if(SOCKET_ERROR==retval)
{
closesocket( g_socketServ );
AfxMessageBox( _T("在要获取服务器文件列表时,绑定端口失败,请检查端口是否已经在用!") );
return ;
}

if( listen( g_socketServ, SOMAXCONN ) != 0 )
{
strMsg.Format( _T("listen错误,错误代号:%d"),WSAGetLastError() );
AfxMessageBox( strMsg );
return;
}

/********发送命令PORT TYPE I LIST给服务器***********/

//分别创建三个线程用来处理 服务器等待连接(accept),客户端主动连接(connect)

g_hAcceptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hAcceptEvent );

g_hConnectEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetEvent( g_hConnectEvent );

HANDLE hAcceptThread, hConnectThread, hRecvThread;
hAcceptThread = CreateThread( NULL, 0, AcceptThreadPorc, NULL, 0, NULL);
hConnectThread = CreateThread( NULL, 0, ConnectThreadPorc, NULL, 0, NULL);
CloseHandle( hAcceptThread );
CloseHandle( hConnectThread );

}

//等待客户端来连接,连接上以后就读取数据
DWORD WINAPI AcceptThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hAcceptEvent, INFINITE );
SOCKET socketConn;
while(1)
{
CString strMsg;
socketConn = accept( g_socketServ, (SOCKADDR*)&addrSock, &len);
if( INVALID_SOCKET == socketConn )
{
strMsg.Format( _T("accept线程错误,错误代号:%d"),WSAGetLastError()

);
AfxMessageBox( strMsg );
return 0;
}
}

//accept后,通过socketConn读取数据

DWORD lpArgument = 0;
int num,sum;
//定义缓冲区的大小
const int BUFSIZE = 4096;
//清空缓冲区
btBuf.RemoveAll ();
btBuf.SetSize (BUFSIZE);

//接收数据
if( !ioctlsocket( socketConn, FIONBIO, &lpArgument) )
return 0;

//获取数据
sum = 0;
while (1)//在这里没有循环结束条件
{
TRY
{
if (!(num = recv( socketConn, (LPTSTR)btBuf.GetData() + sum,

BUFSIZE,0 )||(num == SOCKET_ERROR)))
break;

//sleep(0);
sum += num;
btBuf.SetSize(sum+BUFSIZE);
}
CATCH(CException,e)
{
return 0;
}
END_CATCH
}
closesocket( socketConn );
AfxMessageBox( (LPTSTR)btBuf.GetData() );

CloseHandle( g_hAcceptEvent );
return 0;
}


DWORD WINAPI ConnectThreadPorc( LPVOID lpParameter )
{
WaitForSingleObject( g_hConnectEvent, INFINITE );

SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr(_T("127.0.0.1") );
addrClient.sin_family = AF_INET;
addrClient.sin_port = addrSock.sin_port;
int lenClient = sizeof( addrClient );

connect( g_socketServ, (SOCKADDR*)&addrClient, lenClient );

CloseHandle( g_hConnectEvent );
return 0;
}

现在还是没有结果(没有得到那个AfxMessageBox( (LPTSTR)btBuf.GetData() );)
调试时发现g_socketServ正确创建得到相应的值,但到accept时,会一直停在这句,是因为这函数时同步的,堵塞的吧?

还有地方要注意滴吗?
思路没错吧,就是按照别人那个来写的啊

就是创建一个来接受(accept)服务器(g_socketServ)的连接(得到socketConn),这时我再创建一个线程连接服务器(g_socketServ),(这时候应该那accept就不堵塞了吧?)最后就是通过这个socketConn读取服务器返回的文件列表信息了啊

再次求各位路过大虾们帮个忙
3Q先

18,356

社区成员

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

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