2017-05-21 20 views
0

私は、メインループをブロックせずにクライアントからサーバからのリクエストを受信する方法については役に立たないと考えていましたが、そこに重複がある場合は謝罪しますが、私の目的(UDP)では動作しないTCPバージョンです。CノンブロッキングUDPソケット

現在、サーバーはエコーサーバーなので、ブロックするかどうかは気にしません。

サーバーがクライアントについては

ServerInstance Init(ServerConfiguration c) { 
    ServerInstance n; 
    n.endpoint = socket(PF_INET, SOCK_DGRAM, 0); 
    Exitif(n.endpoint < 0, "Error opening endpoint socket"); 
    setsockopt(n.endpoint, SOL_SOCKET, SO_REUSEADDR, (const void *) &c.trueval, sizeof(int)); 
    setzero((char *) &n.servaddr, sizeof(n.servaddr)); 
    n.servaddr.sin_family = AF_INET; 
    n.servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    n.servaddr.sin_port = htons(c.portno); 
    Exitif(bind(n.endpoint, (struct sockaddr *) &n.servaddr, sizeof(n.servaddr)) < 0, 
    "Error on binding socket to addr"); 
    n.buf = calloc(c.buffersize, sizeof(char)) 
    return n; 
} 

を次のように作成されます。

connection = socket(AF_INET, SOCK_DGRAM, 0); 
    IfThenExit(socket < 0, "Error initializing UDP socket\n"); 
    setzero((char *) &servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htons(PORT); 
    IfThenExit(inet_aton(SRVADDR, &servaddr.sin_addr) == 0, "IPV4 Address Invalid\n"); 
    CleanQueueAdd(&connection, Socket); 

そして、それは上記のようにループし、私はまた、SDLのイベントプールを持っている、と私は知りたいのですがどのように私はプログラムをブロックすることなくそのようなものを実装することができます

if(1) { 
    while(SDL_PollEvent(&e)) { 
    switch(e.type) { 
     case SDL_QUIT: 
     quit = 1; 
     break; 
     case SDL_KEYDOWN: 
     quit = 1; 
     break; 
    } 
    } 
    // Recv here blocks ... 
    // recv(...) 
} 

ありがとう、読んでいただきありがとうございます良い日

+1

ソケットが参照しているネットワーク接続がどのプロトコルを使用しているかは、どのようにソケットを非ブロッキングにして使用するかには影響しません。ソケットインタフェースはネットワークプロトコルに依存しません。 –

+0

2つのオプションがあります。私は1 /ソケットモードをノンブロッキングに設定するコード、または2 /ノンブロッキングコールを指定するオプションを使用してソケット関数を呼び出すコードを見ることを期待しています...しかし、私はこれら2つのどれも見ることができません。閉じる。 – Sebivor

+0

@Seb私はこの質問をした後、ソケットを非ブロッキングモードに設定しましたが、ポーリングや選択に比べて最適ですか?私はCPUサイクルを浪費して読んでいます。 – Whiteclaws

答えて

0

SDLイベントは、任意の非SDLイベントと多重化できないようです。代わりに、select()またはepoll()を使用するセカンダリスレッド、またはそれらの周りのラッパーを作成できます。このスレッドは、ネットワークメッセージを待って、おそらくそれらを読み込んで解析し、SDL_PushEventを使ってメインスレッドに要求を渡します。

+0

Nah、イベントをSDLキューにプッシュしたいのではなく、SDLのようにノンブロッキングな方法でイベントをポーリングする方法を見つけますSDL_PollEventを使用して、pollまたはselectを使用して実装する方法について、ネットの周りに例はありますか?可能であれば、マルチスレッドは不可能です。基本的には、recvを呼び出して、読み込み待ちのパケットがなければすぐに戻りたいと思います。 – Whiteclaws

+0

@Whiteclaws:ソケット上でselect()を使ってIO多重化を行う方法の例が何千もあります。 SDLイベントをどのようにチェックするのですか?実際にSDLイベントやソケットイベントを確認する必要がある場合は、実際にポーリングやビジー待機を行う必要があります。データのソケットをチェックし、イベントのSDLキューを確認し、しばらくスリープして繰り返します。このプロセスは効率的ではありませんが、単一スレッドの使用が可能になります。 –

+0

'select'も' epoll'も排他的にノンブロッキングではありません。 [前のマニュアル](http://pubs.opengroup.org/onlinepubs/7908799/xsh/select.html)、* "...' select() 'ブロックに従って、指定されたタイムアウト間隔まで、指定されたファイルディスクリプタ "*の少なくとも1つに対して指定された条件が真になるまで、*非同期I/O *(ノンブロッキングI/Oとは異なります)です。 – Sebivor