私の問題は次のとおりです。 イーサネット経由でGPIBコントローラを制御するために、Linuxのインターフェイスをプログラミングしています。そうするために、私はTCPソケットを開き、コマンドをコントローラに送るだけです。今のところうまくいきます。 チェックするには、別のスレッドで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;
:しかし、私は(接続のために指定されたタイムアウトを必要とするので)が、私はselect()関数に接続しなければならなかった呼び出します。しかし、私は私のテストサーバーを使用する場合、私は接続することはできません、戻り値0の葉だけを選択してください。 だから今誰かが私のテストサーバーが動作しないと言うかもしれません....しかし、私はテストサーバーに何の問題もなく送信することができます。 多分誰かが私ができることを考えています...?ノンブロッキングソケット接続()呼び出しは、接続して0を返すことがで
ゼロの戻り値は、タイムアウトを示します。これは問題かもしれませんが、投稿された抜粋内にタイムアウト構造体を設定していないようです。マニュアルページ "Linuxでselect()を実行すると、スリープしていない時間が反映されるようにタイムアウトが変更されます。select()が戻った後にタイムアウトが定義されていないと考えてください。値をリセットせずに再度呼び出すと問題が発生します。 –
申し訳ありませんが私のせいで、タイムアウトの構造体の定義を自分のコードに追加するのを忘れました!!!それを修正するつもりです...しかし、それは問題ではないことを意味します:/ /さて、コードには接続を扱う関数全体が含まれています – Toby
あなたはどこにでもソケットを閉じないのですか?あなたはそれを再使用していない、同じソケットで数回接続するのですか? – rodrigo