gpt4 book ai didi

c++ - 第二次进行客户端连接时没有服务器 OnAccept 通知

转载 作者:可可西里 更新时间:2023-11-01 16:44:36 25 4
gpt4 key购买 nike

我编写了一个 MFC C++ 应用程序,其中我的客户端进程执行 TCP MyCAsyncSocket::Connect 到我的服务器进程。服务器进程以 MyCAsyncSocket::OnAccept 响应,然后按照规定Detaches 套接字,创建一个Attaches 套接字的线程,然后读取正在发送的数据。 MSDN 规定在 Detach 之后将 m_hSocket 设置为 NULL。

它工作正常,但只有一次。客户端第二次尝试 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 );
}

尝试 1:在 Detach 之后的 OnAccept 中,我尝试使用 Listen 跟随,但我收到此监听错误:“WSAENOTSOCK:The描述符不是套接字”。不确定这意味着什么。

尝试 2:然后我尝试在后续的 Listen 之前执行 Create,但这导致断言:ASSERT(m_hSocket == INVALID_SOCKET); 定义为:

/*
* This is used instead of -1, since the
* SOCKET type is unsigned.
*/
#define INVALID_SOCKET (SOCKET)(~0)

在原型(prototype)代码中,我只是销毁了监听器套接字并从头开始重新创建它,但是对于生产代码,这是 Not Acceptable ,因为 Detaching 和 reAttach 的整个想法ing 是为了确保套接字线程的监听能力永远不会中断超过微秒。

有人知道为后续 Connections 准备套接字的正确语义应该是什么吗?

最佳答案

如果我没看错的话,您可以在监听 套接字上调用 AsyncSelect(FD_READ|FD_CLOSE) - 我认为您实际上想在新接受的套接字 (syncSocket) 上调用它。

我希望调用 AsyncSelect(FD_READ|FD_CLOSE) 可以清除监听套接字上的 FD_ACCEPT 通知 - 从而确保在以后与监听套接字建立连接时不会调用 OnAccept。

此外 - 当您在上面设置 m_hSocket = NULL 时,您将 listening 套接字的句柄设为 NULL,而不是新接受的套接字 (syncSocket) 的句柄。

此外,如果我正确阅读了 MSDN ( https://msdn.microsoft.com/en-us/library/05sz8hz8.aspx ),Detach() 方法本身会将相关句柄置为 NULL,您无需自己执行此操作。 [我想你也不会 - 因为 m_hSocket 应该是 syncSocket 的私有(private)成员]

我希望您的 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

}

关于c++ - 第二次进行客户端连接时没有服务器 OnAccept 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38921888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com