CAsyncSocket的OnAccept究竟是何时触发? 问题1:如果是在Accept后触发,那么在OnAccept里面应该响应什么呢?是否Accept失败也能触发OnAccept?问题2:CAsyncSocket是非阻塞的,如何实现获取连接?坐等高人详细解释CAsyncSocket的服务器端实现 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 问题1: 答案: 有客户端请求连接时响应, Accept失败跟触发OnAccept没有关系,Accept只是负责判断是否监听成功,然后进行通信。问题2:答案: 可以在OnAccept里捕获客户端的连接,然后获取客户端的IP,下面是获取连接的代码//有连接时触发,负责监听客户端void CDistributor::OnAccept(int nErrorCode){ CClientSocket *psocket = new CClientSocket(); if (Accept(*psocket))//如果监听成功,就可以获取客户端的信息进行通信了 { CString str1; CString str2(_T("客户端:")); unsigned int m_port=7000; psocket->GetPeerName(str1,m_port)//获取到指定IP和端口 psocket->AsyncSelect(FD_READ|FD_WRITE);//投递事件 //下面的处理就看你了呵呵 CAsyncSocket::OnAccept(nErrorCode);}http://www.cnblogs.com/wqj1212/archive/2009/03/18/1415786.html 博客园,这个比较详细呵呵! 那岂不是要时时监听,CAsyncSocket是非阻塞的难道要while(1){Listen(5);}要不然,我怎么知道客户端什么时候连接,等它连接时服务端程序都执行完了还怎么监听啊 Listen一次即可,以后客户端每次connect。OnAccept都会被触发 然而,最不容易被初学Socket编程的人理解的,也是本文最要提醒的一点是,客户方在使用CAsyncSocket::Connect()时,往往返回一个WSAEWOULDBLOCK的错误(其它的某些函数调用也如此),实际上这不应该算作一个错误,它是Socket提醒我们,由于你使用了非阻塞Socket方式,所以(连接)操作需要时间,不能瞬间建立。既然如此,我们可以等待呀,等它连接成功为止,于是许多程序员就在调用Connect()之后,Sleep(0),然后不停地用WSAGetLastError()或者CAsyncSocket::GetLastError()查看Socket返回的错误,直到返回成功为止。这是一种错误的做法,断言,你不能达到预期目的。事实上,我们可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发,CAsyncSocket::OnConnect()是要表明Socket要么连接成功了,要么连接彻底失败了。至此,我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了,还是失败了。 类似的,Send()如果返回WSAEWOULDBLOCK错误,我们在OnSend()处等待,Receive()如果返回WSAEWOULDBLOCK错误,我们在OnReceive()处等待,以此类推。 还有一点,也许是个难点,那就是在客户方调用Connect()连接服务方,那么服务方如何Accept(),以建立连接的问题。简单的做法就是在监听的Socket收到OnAccept()时,用一个新的CAsyncSocket对象去建立连接,例如: void CMySocket::OnAccept( int ErrCode ) { CMySocket* pSocket = new CMySocket; Accept( *pSocket ); } 于是,上面的pSocket和客户方建立了连接,以后的通信就是这个pSocket对象去和客户方进行,而监听的Socket仍然继续在监听,一旦又有一个客户方要连接服务方,则上面的OnAccept()又会被调用一次。当然pSocket是和客户方通信的服务方,它不会触发OnAccept()事件,因为它不是监听Socket。 不需要啊,初始化之后listen一次就够了,只需要设置你要监听的客户端套接字数就可以了//初始化分发服务器Socketvoid CDistributor::CreateServer(){ if(this->m_hSocket == INVALID_SOCKET)//服务器处于未连接状态 { bool bflag = this->Create(65432,SOCK_STREAM,FD_ACCEPT); if(bflag==false) { AfxMessageBox(_T("服务器建立套接字,请确保端口未被占用")); this->Close(); } else { //设置为32K int nSendBuf=60*1024; //设置套接口 setsockopt(this->m_hSocket,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(nSendBuf)); } if(!this->Listen(100))//监听客户端连接数 { int nerrorcode = this->GetLastError(); if (nerrorcode==WSAEWOULDBLOCK) { AfxMessageBox(_T("Socket Error")); this->Close(); PostQuitMessage(0); } } }} 最好是自己写代码,然后加断点测试下,然后你看是不是这样的,只要服务器套接字正确创建之后,然后设置监听的客户端个数,重定义OnAccept函数,客户端每连接一次OnAccept都会执行,客户端可以写个for循环反复连下,而Listen是套接字初始化的时候就设置了的,所以之后通信的操作跟它没关系了。 列表控件 选中项上下移动 [散分]统计一下:大家的年龄,性别 editview 棘手的问题,大家帮帮忙 网上文件下载,了解xmlhttp的朋友进来看下 在不同对象之间使用sizeof出现的问题。 有没有什么工具可以将rm转为Mp3或wav的? 怎样为通用控件指定资源id? 被封杀了吗?为什么进入CSDN的基础类时显示"文本内容中发现无效字符"??? 看过《WINDOWS 程序设计》5th的请进 哪里有关于WinApi函数的文档? 问个有难度的问题:怎么实现窗口的内容等比例的缩放? 为什么InvalidateRect调用后,我的显示窗口没有刷新为背景色.
void CDistributor::OnAccept(int nErrorCode)
{
CClientSocket *psocket = new CClientSocket(); if (Accept(*psocket))//如果监听成功,就可以获取客户端的信息进行通信了
{
CString str1;
CString str2(_T("客户端:"));
unsigned int m_port=7000;
psocket->GetPeerName(str1,m_port)//获取到指定IP和端口
psocket->AsyncSelect(FD_READ|FD_WRITE);//投递事件 //下面的处理就看你了呵呵
CAsyncSocket::OnAccept(nErrorCode);
}http://www.cnblogs.com/wqj1212/archive/2009/03/18/1415786.html 博客园,这个比较详细呵呵!
while(1)
{
Listen(5);
}
要不然,我怎么知道客户端什么时候连接,等它连接时服务端程序都执行完了还怎么监听啊
类似的,Send()如果返回WSAEWOULDBLOCK错误,我们在OnSend()处等待,Receive()如果返回WSAEWOULDBLOCK错误,我们在OnReceive()处等待,以此类推。
还有一点,也许是个难点,那就是在客户方调用Connect()连接服务方,那么服务方如何Accept(),以建立连接的问题。简单的做法就是在监听的Socket收到OnAccept()时,用一个新的CAsyncSocket对象去建立连接,例如: void CMySocket::OnAccept( int ErrCode )
{
CMySocket* pSocket = new CMySocket;
Accept( *pSocket );
}
于是,上面的pSocket和客户方建立了连接,以后的通信就是这个pSocket对象去和客户方进行,而监听的Socket仍然继续在监听,一旦又有一个客户方要连接服务方,则上面的OnAccept()又会被调用一次。当然pSocket是和客户方通信的服务方,它不会触发OnAccept()事件,因为它不是监听Socket。
不需要啊,初始化之后listen一次就够了,只需要设置你要监听的客户端套接字数就可以了//初始化分发服务器Socket
void CDistributor::CreateServer()
{
if(this->m_hSocket == INVALID_SOCKET)//服务器处于未连接状态
{
bool bflag = this->Create(65432,SOCK_STREAM,FD_ACCEPT);
if(bflag==false)
{
AfxMessageBox(_T("服务器建立套接字,请确保端口未被占用"));
this->Close();
}
else
{
//设置为32K
int nSendBuf=60*1024;
//设置套接口
setsockopt(this->m_hSocket,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(nSendBuf));
}
if(!this->Listen(100))//监听客户端连接数
{
int nerrorcode = this->GetLastError();
if (nerrorcode==WSAEWOULDBLOCK)
{
AfxMessageBox(_T("Socket Error"));
this->Close();
PostQuitMessage(0);
}
} }
}