check select errors better
This commit is contained in:
parent
76f196206b
commit
8a0afef825
@ -171,11 +171,16 @@ namespace ix
|
|||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 1 * 1000; // 1ms
|
timeout.tv_usec = 1 * 1000; // 1ms timeout
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(_sockfd, &rfds);
|
FD_SET(_sockfd, &rfds);
|
||||||
select(_sockfd + 1, &rfds, nullptr, nullptr, &timeout);
|
|
||||||
|
if (select(_sockfd + 1, &rfds, nullptr, nullptr, &timeout) < 0 &&
|
||||||
|
(errno == EBADF || errno == EINVAL))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ namespace ix
|
|||||||
{
|
{
|
||||||
errMsg = "no error";
|
errMsg = "no error";
|
||||||
|
|
||||||
int fd = (int) socket(address->ai_family,
|
int fd = socket(address->ai_family,
|
||||||
address->ai_socktype,
|
address->ai_socktype,
|
||||||
address->ai_protocol);
|
address->ai_protocol);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
errMsg = "Cannot create a socket";
|
errMsg = "Cannot create a socket";
|
||||||
@ -56,33 +56,14 @@ namespace ix
|
|||||||
// block us for too long
|
// block us for too long
|
||||||
SocketConnect::configure(fd);
|
SocketConnect::configure(fd);
|
||||||
|
|
||||||
if (::connect(fd, address->ai_addr, address->ai_addrlen) == -1)
|
if (::connect(fd, address->ai_addr, address->ai_addrlen) == -1
|
||||||
|
&& errno != EINPROGRESS)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
closeSocket(fd);
|
||||||
if (WSAGetLastError() == WSAEWOULDBLOCK) errno = EINPROGRESS;
|
errMsg = strerror(errno);
|
||||||
#endif
|
return -1;
|
||||||
if (errno != EINPROGRESS)
|
|
||||||
{
|
|
||||||
closeSocket(fd);
|
|
||||||
errMsg = std::string("Connect error in ::connect:") + strerror(errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use select to see if the connect did succeed.
|
|
||||||
fd_set wfds;
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
FD_SET(fd, &wfds);
|
|
||||||
|
|
||||||
fd_set efds;
|
|
||||||
FD_ZERO(&efds);
|
|
||||||
FD_SET(fd, &efds);
|
|
||||||
|
|
||||||
// 50ms select timeout
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 50 * 1000;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (isCancellationRequested()) // Must handle timeout as well
|
if (isCancellationRequested()) // Must handle timeout as well
|
||||||
@ -91,14 +72,31 @@ namespace ix
|
|||||||
errMsg = "Cancelled";
|
errMsg = "Cancelled";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use select to check the status of the new connection
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 10 * 1000; // 10ms timeout
|
||||||
|
fd_set wfds;
|
||||||
|
fd_set efds;
|
||||||
|
|
||||||
select(fd + 1, nullptr, &wfds, &efds, &timeout);
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(fd, &wfds);
|
||||||
|
FD_ZERO(&efds);
|
||||||
|
FD_SET(fd, &efds);
|
||||||
|
|
||||||
|
if (select(fd + 1, nullptr, &wfds, &efds, &timeout) < 0 &&
|
||||||
|
(errno == EBADF || errno == EINVAL))
|
||||||
|
{
|
||||||
|
closeSocket(fd);
|
||||||
|
errMsg = std::string("Connect error, select error: ") + strerror(errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing was written to the socket, wait again.
|
// Nothing was written to the socket, wait again.
|
||||||
if (!FD_ISSET(fd, &wfds)) continue;
|
if (!FD_ISSET(fd, &wfds)) continue;
|
||||||
|
|
||||||
// Something was written to the socket. Check for errors.
|
// Something was written to the socket. Check for errors.
|
||||||
|
|
||||||
int optval = -1;
|
int optval = -1;
|
||||||
socklen_t optlen = sizeof(optval);
|
socklen_t optlen = sizeof(optval);
|
||||||
|
|
||||||
@ -113,7 +111,7 @@ namespace ix
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
closeSocket(fd);
|
closeSocket(fd);
|
||||||
errMsg = std::string("Connect error in getsockopt:") + strerror(optval);
|
errMsg = strerror(optval);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -124,7 +122,7 @@ namespace ix
|
|||||||
}
|
}
|
||||||
|
|
||||||
closeSocket(fd);
|
closeSocket(fd);
|
||||||
errMsg = "connect timed out";
|
errMsg = "connect timed out after 60 seconds";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,19 +146,28 @@ namespace ix
|
|||||||
// Return value of std::async, ignored
|
// Return value of std::async, ignored
|
||||||
std::future<void> f;
|
std::future<void> f;
|
||||||
|
|
||||||
// Select arguments
|
|
||||||
fd_set rfds;
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 10 * 1000; // 10ms
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (_stop) return;
|
if (_stop) return;
|
||||||
|
|
||||||
|
// Use select to check whether a new connection is in progress
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 10 * 1000; // 10ms timeout
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(_serverFd, &rfds);
|
FD_SET(_serverFd, &rfds);
|
||||||
select(_serverFd + 1, &rfds, nullptr, nullptr, &timeout);
|
|
||||||
|
if (select(_serverFd + 1, &rfds, nullptr, nullptr, &timeout) < 0 &&
|
||||||
|
(errno == EBADF || errno == EINVAL))
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "SocketServer::run() error in select: "
|
||||||
|
<< strerror(Socket::getErrno());
|
||||||
|
logError(ss.str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!FD_ISSET(_serverFd, &rfds))
|
if (!FD_ISSET(_serverFd, &rfds))
|
||||||
{
|
{
|
||||||
|
@ -158,9 +158,8 @@ namespace ix
|
|||||||
{
|
{
|
||||||
int N = (int) _rxbuf.size();
|
int N = (int) _rxbuf.size();
|
||||||
|
|
||||||
int ret;
|
|
||||||
_rxbuf.resize(N + 1500);
|
_rxbuf.resize(N + 1500);
|
||||||
ret = _socket->recv((char*)&_rxbuf[0] + N, 1500);
|
ssize_t ret = _socket->recv((char*)&_rxbuf[0] + N, 1500);
|
||||||
|
|
||||||
if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
|
if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
|
||||||
_socket->getErrno() == EAGAIN)) {
|
_socket->getErrno() == EAGAIN)) {
|
||||||
|
@ -16,7 +16,8 @@ using namespace ix;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const std::string WEBSOCKET_DOT_ORG_URL("wss://echo.websocket.org");
|
// const std::string WEBSOCKET_DOT_ORG_URL("wss://echo.websocket.org");
|
||||||
|
const std::string WEBSOCKET_DOT_ORG_URL("wss://api.cobra.mobilewar-online.com/v2?appkey=ADdc208AB26B911F4cB05bFeedD8EbBA");
|
||||||
const std::string GOOGLE_URL("wss://google.com");
|
const std::string GOOGLE_URL("wss://google.com");
|
||||||
const std::string UNKNOWN_URL("wss://asdcasdcaasdcasdcasdcasdcasdcasdcasassdd.com");
|
const std::string UNKNOWN_URL("wss://asdcasdcaasdcasdcasdcasdcasdcasdcasassdd.com");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user