rti*_*277 9 c++ sockets mfc tcplistener
我编写了一个MFC C++应用程序,我的客户端进程MyCAsyncSocket::Connect
在我的服务器进程中执行TCP .服务器进程用一个响应MyCAsyncSocket::OnAccept
,然后Detach
按照规定对套接字进行响应,创建一个Attach
该套接字的线程,然后该套接字读取正在发送的数据.MSDN规定m_hSocket在之后设置为NULL Detach
.
它工作正常,但只有一次.客户端第二次尝试访问Connect
相同的套接字地址时,不会OnAccept
发生通知.这是服务器代码:
void MyCAsyncSocket::OnAccept( int nErrorCode )
{
BOOL socketResult = FALSE;
CAsyncSocket syncSocket;
Accept( syncSocket );
AsyncSelect( FD_READ | FD_CLOSE );
SOCKET socket = syncSocket.Detach();
m_hSocket = NULL; // prescribed by msdn
... // go attach the socket in a worker thread, read the socket and do work
// try to re-establish listener.
...Create( // error: attempt 2: ASSERT(m_hSocket == INVALID_SOCKET)
endPoint.portNumber, // ok: same as client port number
SOCK_STREAM,
FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
endPoint.ipAddress // ok: same as client ip address
);
...Listen(); // error: attempt 1: no error case, but still doesn't work
CAsyncSocket::OnAccept( nErrorCode );
}
Run Code Online (Sandbox Code Playgroud)
尝试1:在我尝试跟随OnAccept
之后,但是我得到了这个监听错误:"WSAENOTSOCK:描述符不是套接字".不确定这意味着什么.Detach
Listen
尝试2:然后我尝试Create
在跟进之前做了一次Listen
,但是这导致了一个断言:ASSERT(m_hSocket == INVALID_SOCKET);
定义为:
/*
* This is used instead of -1, since the
* SOCKET type is unsigned.
*/
#define INVALID_SOCKET (SOCKET)(~0)
Run Code Online (Sandbox Code Playgroud)
在原型代码中,我只是销毁了侦听器套接字并从头开始重新创建它,但是对于生产代码,这是不可接受的,因为整个构思Detach
和重新Attach
构建是为了确保套接字线程的侦听能力永远不会被中断.比微秒.
有人知道为后续Connect
离子准备套接字应该是什么样的语义吗?
如果我正确地阅读了本文,您将在侦听套接字上调用 AsyncSelect(FD_READ|FD_CLOSE) - 我认为您实际上想在新接受的套接字 (syncSocket) 上调用它。
我希望调用 AsyncSelect(FD_READ|FD_CLOSE) 可以清除侦听套接字上的 FD_ACCEPT 通知 - 从而确保在将来与侦听套接字建立连接时不会调用 OnAccept。
此外,当您在上面设置 m_hSocket = NULL 时,您将侦听套接字的句柄设置为 NULL ,而不是新接受的套接字 (syncSocket) 的句柄。
此外,如果我正确阅读 MSDN(https://msdn.microsoft.com/en-us/library/05sz8hz8.aspx),Detach() 方法本身会将相关句柄设为 NULL,并且您不需要执行以下操作这个你自己。[我希望你也可以 - 因为 m_hSocket 应该是syncSocket的私有成员]
我希望您的 OnAccept 代码看起来更像:
void MyCAsyncSocket::OnAccept( int nErrorCode )
{
BOOL socketResult = FALSE;
CAsyncSocket syncSocket;
Accept( syncSocket );
SOCKET socket = syncSocket.Detach();
... // go attach the socket in a worker thread, which reads the socket and does work
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
248 次 |
最近记录: |