我的問題是以下內容: 我正在編程接口在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