我的问题是以下内容: 我正在编程接口在Linux中通过以太网控制GPIB控制器。为此,我打开一个TCP套接字并将这些命令发送给Controller。到目前为止,这工作得很好。我在为我的接口编写某种单元测试时发生了这个问题: 要检查我是否在单独的线程中使用来自boost lib的tcp接受器,并且只是连接到它而不是实际的控制器。这也起作用,但只要来自接口的connect()调用被阻塞即可。然而,因为我需要为连接指定的超时()调用我不得不用select()函数连接:Linux的TCP连接与选择()失败在测试服务器
// Open TCP Socket
m_Socket = socket(PF_INET,SOCK_STREAM,0);
if(m_Socket < 0)
{
m_connectionStatus = STATUS_CLOSED;
return ERR_NET_SOCKET;
}
struct sockaddr_in addr;
inet_aton(m_Host.c_str(), &addr.sin_addr);
addr.sin_port = htons(m_Port);
addr.sin_family = PF_INET;
// Set timeout values for socket
struct timeval timeouts;
timeouts.tv_sec = SOCKET_TIMEOUT_SEC ; // const -> 5
timeouts.tv_usec = SOCKET_TIMEOUT_USEC ; // const -> 0
uint8_t optlen = sizeof(timeouts);
if(setsockopt(m_Socket, SOL_SOCKET, SO_RCVTIMEO,&timeouts,(socklen_t)optlen) < 0)
{
m_connectionStatus = STATUS_CLOSED;
return ERR_NET_SOCKET;
}
// Set the Socket to TCP Nodelay (Send immediatly after a send/write command)
int flag_TCP_nodelay = 1;
if ((setsockopt(m_Socket, IPPROTO_TCP, TCP_NODELAY,
(char *)&flag_TCP_nodelay, sizeof(flag_TCP_nodelay))) < 0)
{
m_connectionStatus = STATUS_CLOSED;
return ERR_NET_SOCKET;
}
// Save Socket Flags
int opts_blocking = fcntl(m_Socket, F_GETFL);
if (opts_blocking < 0)
{
return ERR_NET_SOCKET;
}
int opts_noblocking = (opts_blocking | O_NONBLOCK);
// Set Socket to Non-Blocking
if (fcntl(m_Socket, F_SETFL, opts_noblocking)<0)
{
return ERR_NET_SOCKET;
}
// Connect
if (connect(m_Socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
// EINPROGRESS always appears on Non Blocking connect
if (errno != EINPROGRESS)
{
m_connectionStatus = STATUS_CLOSED;
return ERR_NET_SOCKET;
}
// Create a set of sockets for select
fd_set socks;
FD_ZERO(&socks);
FD_SET(m_Socket,&socks);
// Wait for connection or timeout
int fdcnt = select(m_Socket+1,NULL,&socks,NULL,&timeouts);
if (fdcnt < 0)
{
return ERR_NET_SOCKET;
}
else if (fdcnt == 0)
{
return ERR_TIMEOUT;
}
}
//Set Socket to Blocking again
if(fcntl(m_Socket,F_SETFL,opts_blocking)<0)
{
return ERR_NET_SOCKET;
}
m_connectionStatus = STATUS_OPEN;
return x2e::OK;
如果我用这个功能,我仍然可以连接真实控制器上,并与它进行通信。但是,如果我使用我的测试服务器,我只是无法连接,只选择返回值为0的叶子。 因此,现在有人可能会说我的测试服务器不工作....但如果我使用阻塞连接()打电话我可以发送到我的测试服务器没有任何问题... 也许有人有一个想法我可以做什么......?
的零的返回值表示超时。这可能会也可能不是问题,但您似乎并未在发布的摘录中设置超时结构。引用手册页“在Linux上,select()修改超时以反映未睡眠的时间量......考虑超时在select()返回后未定义。”如果您在不重置值的情况下再次调用它,会导致问题。 –
对不起我的错,我忘了将timeouts结构的定义添加到我的代码中!要解决这个问题......但这也意味着这不是问题:/ /所以现在的代码包含处理连接的整个功能 – Toby
你是否知道你没有关闭任何地方的插座?你没有重复使用它,使用相同的套接字多次连接,你呢? – rodrigo