gpt4 book ai didi

c++ - 担心处理对 accept() 的错误调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:01:35 26 4
gpt4 key购买 nike

我正在写一个 MUD出于个人学习目的的服务器,我很高兴地设法将套接字内容包装成几个类,并且一切似乎都在正常工作;服务器监听并接受连接,当前从客户端获取文本并将其立即发回。

问题是我不太确定如何处理对返回 WSAEWOULDBLOCK 或有效套接字以外的内容的 accept() 的调用。我是否只是将新套接字重置为 0 并返回,可能会出现一条错误消息,说明发生了一些不好的事情?这就是我目前正在做的事情,如果它发生 20 次,我将关闭服务器。

void MUDControlSocket::Poll()
{
// create a new connection here
timeval timeout;

FD_ZERO(&ReadSet);
FD_ZERO(&WriteSet);
FD_ZERO(&ExceptionSet);

TopSocket = GetSocket();
NewSocket = 0;
FD_SET( GetSocket(), &ReadSet );

if( SocketList.size() > 0 )
{
for( sockIter iter = SocketList.begin(); iter != SocketList.end(); ++iter )
{
FD_SET((*iter)->GetSocket(), &ReadSet);
FD_SET((*iter)->GetSocket(), &WriteSet);
FD_SET((*iter)->GetSocket(), &ExceptionSet);
TopSocket = (*iter)->GetSocket();
}
}

if( select( TopSocket+1, &ReadSet, &WriteSet, &ExceptionSet, &timeout ) == SOCKET_ERROR )
{
cout << "Error on select() call: " << SocketErrorType(WSAGetLastError()) << endl;

delete this;
exit(EXIT_FAILURE);
}

// as long as everything is working correctly, this if block should always be entered UNLESS a new connection is accepted
if( (NewSocket = accept(GetSocket(), NULL, NULL) ) == INVALID_SOCKET )
{
if( WSAGetLastError() == WSAEWOULDBLOCK ) // it's not an actual problem. just nothing to connect to yet
return;
NewSocket = 0;
static int count = 0;
cout << "Error on accepting new connection: " << SocketErrorType(WSAGetLastError()) << endl;
if( ++count >= 20 )
done = true;
return;
}

SocketList.push_back(new MUDSocket(NewSocket)); // only happens if accept DOES NOT return a value of INVALID_SOCKET i.e. a new connection was accepted
TopSocket = NewSocket;
NewSocket = 0;
}

TopSocket 和 NewSocket 属于 SOCKET 类型并在文件范围内声明。 SocketList 是 MUDSocket* 的 std::list,而 MUDControlSocket 作为单例从 MUDSocket 派生。

如果您需要更多信息,请告诉我,感谢您的帮助。

最佳答案

首先:不要将套接字设置为 0:这是某些 *NIX 系统上套接字的有效 fd,这是一个坏习惯。假设唯一无效的套接字 fd 是 -1。做任何其他事情都会在以后给你真正的软件带来真正的错误(相信我:我是根据调试使用 0 作为无效套接字 fd 的代码的经验说的)。

除此之外,我想说的只是引发一个异常:accept 不应该失败,除非你用完资源,这应该是异常和错误。 C++ 有一种处理此类事情的机制,那就是异常。

顺便说一句:delete this 几乎总是一个非常糟糕的主意,在代码中间退出可能会使调试变得困难(改为抛出异常)并让调用者执行退出 if需要)而不是尝试接受带有 accept 的套接字,您可以使用 select 来告诉您是否有任何东西可以接受 - 并将特殊情况处理移出的功能只能在那里选择。您可以更进一步并实现专门的观察​​者模式(就像我大约一个月前在 my podcast 上所做的那样)不仅可以练习您的网络代码,还可以练习您的设计模式。这也将有助于使您的代码更具可移植性,并可在以后重复使用。

HTH

关于c++ - 担心处理对 accept() 的错误调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5465730/

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