2016-05-01 6 views
-2

私はサーバーにリクエストを送るアプリケーションを構築しています。接続する時間を制御する方法を実装する必要がありますサーバ。誰かが私にconnect()関数のカスタムタイムアウトの例を表示できますか?

私は10秒後にconnect()関数を終了したいと思います。 select()とnon-blockingソケットについて読んだことがありますが、どのように動作するのか完全に理解していません。

誰かが私にこれをどのように行うことができるかの非常に簡単な例を教えてもらえますか? C.を使用してありがとう。

また、同じタイムアウトをsend関数とrecv関数にも追加したいと思います。

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <arpa/inet.h> 
#include <fcntl.h> 
#include <errno.h> 

int main(void) { 

struct sockaddr_in server; 
int sockfd; 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 

server.sin_addr.s_addr = inet_addr("10.0.0.1"); 
server.sin_family = AF_INET; 
server.sin_port = htons(atoi("80")); 

fcntl(sockfd, F_SETFL, O_NONBLOCK); 

struct timeval tv; 
fd_set writefds; 

tv.tv_sec = 5; 
tv.tv_usec = 500000; 

FD_ZERO(&writefds); 
FD_SET(sockfd, &writefds); 

connect(sockfd, (struct sockaddr *)&server, sizeof(server)); 

if (errno == EINPROGRESS) 
{ 
     printf("In progress"); 
} 

select(sockfd+1, NULL, &writefds, NULL, &tv); 

なぜ、errnoのif条件がタイムアウト後まで表示されないのか説明できますか?それは私には意味がありません。そして、これを正しく処理するためにここで調べるべき追加のコードがあります。ありがとう。

+0

以前のシステムコールが-1を返さない限り、 'errno'をテストするのは正しくありません。 'socket()、fcntl()、connect()、select()'、...のようにすべての*システムコールをテストする必要があります。 – EJP

+0

ありがとう。接続の前後にprintfステートメントがなぜタイムアウトが成功するまで印刷されないのか、私はちょうど何が起こって混乱している? – user2342434242

+0

'fcntl()'が失敗したため、エラーチェックしなかったので、見つからなかったので、ソケットはまだブロックモードです。誰かがあなたのコードに大失敗したことを指摘すると、「OK」は適切な応答ではありません。訂正して再テストすることになっています。 – EJP

答えて

2

実際のコードを書き込むのではなく、概要を説明します。 (私はLinuxなどと想定しています)

  1. ソケットを作成します。
  2. ソケットfdでfcntlを呼び出し、ソケットを非ブロックにするには O_NONBLOCKオプションを設定します。 (socket コールでSOCK_NONBLOCKオプションを指定すると、 になる可能性があります)。
  3. connectに電話してください。すぐに戻ります。ほとんどの はエラーEINPROGRESSで「失敗」する可能性があります。つまり、 接続操作が進行中です。
  4. selectまたはpollを呼び出して、ソケットfdが書き込み可能になるまで待ちます( )。これらの呼び出しの両方には、 タイムアウトオプションがあります。
  5. ソケット(すなわち、あなたのselectまたはpoll がタイムアウトしない)書き込み可能になった場合、connectは返すことで成功したか失敗したか を示すであろう、SO_ERRORの値を取得するために getsockoptを呼び出して、接続状態を確認成功するとエラーコード または0が返されます。

あなたはsend sおよびrecv Sだけでなく(あなたが読みになることをソケットを待つ必要が受け取るためにではあるが)をタイムアウトするために、同じ技術を使用することができます。

詳しくは、socket(2)、connect(2)、select(2)、poll(2)、socket(7)、getsockopt(2)のマニュアルページを参照してください。

+0

返信いただきありがとうございます。非常に役立ちます。私はまだすべてを完了するためにいくつかの問題を抱えています、私はいくつかのコードで私の質問を更新しました。 – user2342434242

関連する問題