2017-10-05 5 views
0

私はUDPがコネクションレスであることを知っていますが、自分のサーバーに接続する新しいUDPクライアントを処理する新しいスレッドを生成できますか?使用している場合、各クライアントのUDP「接続」を築くと、それには、OpenSSLによって行われているようにそれを処理するために新しいスレッドをフォークしする方法は新しいUDP「接続」を処理するために新しいスレッドを生成しますか?

void *handle_connection(void *param) 
{ 
    // read data 
    ret = recvfrom(..,0,..); 
} 


// Wait for connection using MSG_PEEK 
ret = recvfrom(.., MSG_PEEK,..); 

// New thread to handle client connection 
pthread_t conn_thread; 
ret = pthread_create(..., handle_connection); 

あります:

は、私は基本的にこれをやろうとしていますDTLS?

OpenSSLでは、DTLS_listen()を使用して、UDPクライアントが接続してから新しいスレッドを開始し、そのスレッドにUDPソケットを渡し、通常の読み取り/書き込み操作を使用できるようにします。しかし、うまくいくためには、udpソケット上でbind()とconnect()の2つの追加呼び出しを行う必要があります。

ここでも同じアプローチを試みましたが、サーバー上のクライアントから受信した各データグラムに対して新しいスレッドを開くことになりました。

+0

あなたはできますか?何故なの?新しいスレッドを作成して、必要なものを実行することができます。 –

+0

できます。しかし、そうすることに何らかの利益があることは明らかではありません。単一のスレッドは、単一のソケットを使用して任意の数のUDPクライアントを処理できます。 –

+0

@JeremyFriesner BIOとSSLオブジェクトの周りにあなたのソケットをラップするときにOpenSSLですることができます...私はここでも同じことができるのだろうかと思っていました。 – user2584587

答えて

2

と思います。しかし、私は保証が何であるか分かりません。

基本的な考え方は次のとおりです。

  1. 、サーバソケットを作成し、それにSO_REUSEADDRを設定し、 サーバポートにバインドし、その上にデータを受信するのを待ちます。
  2. recvfromは、次の受信データグラムとそれが送信された のアドレスを示します。
  3. 初期データグラムとアドレスを新しいスレッドに渡します。
  4. 新しいスレッドで、新しいソケットを作成します(もう一度SO_REUSEADDRでバインドします)。今すぐconnectピアアドレスに新しいソケット。
  5. 戻るここでの考え方は、あなたが常に一つの「未接続」のソケットを維持することである2

進みます。新しいピアを取得すると、そのピアに接続されている新しいソケットが作成されます。ソケットが特にリモートピアに接続されている場合、カーネルはそのピアから受信したデータグラムをそのソケットに渡します。それ以外の場合は、未接続のソケットにデータグラムを配信します。

OSはで、は未接続のソケットではなく、接続されたソケットにしかデータグラムを送信できないのでしょうか?この方法でうまくいくと思いますが、それは私のLinuxのボックスで動作するようです。下記のpython3のコードを参照してください(nc -u localhost 9999をクライアントとして使用できます)。

#!/usr/bin/env python3 
from threading import Thread 
import socket 

def client_thread(addr, msg): 
    # Create a new socket and connect it to the peer. 
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    sock.bind(('', 9999)) # Maybe omit -- see below 
    sock.connect(addr) 
    # Maybe set SO_RCVTIMEO to cause timeout on receive and 
    # cause client thread to bail? 
    while True: 
     sock.send(msg) 
     msg = sock.recv(1024) 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
sock.bind(('', 9999)) 

threads = [] 

while True: 
    # Receive datagram on unconnected socket 
    msg, addr = sock.recvfrom(1024) 

    # Send connected socket and datagram 
    th = Thread(target=client_thread, args=(addr, msg)) 
    th.start() 
    threads.append(th) 

あなたはおそらく、あなたのクライアントが消えた場合、彼らは永遠に周りにハングアップしないように、最終的にはサブスレッドを殺すのいくつかの方法があります。

client_threadに新しいソケットをバインドすることを省略すると、カーネルは新しいソケットのローカルアドレス用の未使用ポートを選択することになりますが、クライアントはそのアドレスに注意する必要があります最初の応答を受信し、将来のデータグラムをそのアドレスに直接送信します。これは同じことを達成し、多くの点でよりきれいになるでしょう。

クライアント側はこの(再びデモ用のPythonを使用して)のようなものが考えられます。

#!/usr/bin/env python3 
import socket 

# Initial request sent to well-known port 
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
addr = ('localhost', 9999) 

for n in range(5): 
    print('Send to {}'.format(addr)) 
    sock.sendto(b'Hello', addr) 
    response, addr = sock.recvfrom(1024) 
    # Subsequent requests sent to whoever responded to last request 
    print('Got response {} from {}'.format(response, addr)) 
関連する問題