1

私は次の設定をしています:

サーバーは、Bluetoothを介して、個別の信号を送信している複数のデバイスに接続します。次に、デバイスが接続されているサーバーに(おそらくWebサービスを介して)照会し、必要なデバイスからの信号をリッスンできるn個のクライアントが存在します。

これを実装する最良の方法は、サーバーがBTを介してデバイスに接続するときに、ローカルポートへのソケットを開き、そこにデータを送信することだと思います。クライアントが利用可能なデバイスを要求すると、サーバーは辞書を返し、クライアントはそのポートをリッスンする必要があります。

しかし、ソケットの実装に問題があります。信号を作成してローカルポートに書き込むにはどうすればよいですか?

これは私がこれまでに得たものです:

class Device {
    ...
    public EndPoint Connect() {
        // create a bt connection to the device

        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        var endPoint = new IPEndPoint(IPAddress.Parse(_localIp), 0);
        _socket.Bind(endPoint);

        return endPoint;
    }

    private void OnBtDataReceived(object sender, wclDataEventArgs e) {
        _socket.Send(e.Data);
    }
}

しかし、_socket.Send(e.Data);に到達すると 次の例外が発生します。

ソケットが接続されておらず、(sendto呼び出しを使用してデータグラムソケットで送信する場合)アドレスが指定されていないため、データの送受信要求は許可されませんでした

これは正しいアプローチですが、データを読み取るために誰かをソケットに接続する必要がありますか?

4

2 に答える 2

1

コメントが接続を確立する必要がない場所を示唆しているので、UDPブロードキャストを使用できます。サーバーは1つのポートでデータを送信するだけで、関心のあるクライアントはそのポートでそのデータを受信できます。

デバイスを区別したい場合は、すべてのデバイスのデータを別々のポートでブロードキャストする必要があります。多くのデバイスを使用している場合、これは大量の(不要な)ネットワークトラフィックになる可能性があります。

もう1つのオプションは、TCPを使用することです。クライアントからの着信接続をリッスンするサーバー:

_socket.Bind(new IPEndPoint(IPAddress.Any, 1234));
_socket.Listen(10);
_socket.BeginAccept(onAccept, _socket);

onAcceptでは、clientsocketにアクセスでき、データを送信したり、ソケットへの参照をどこかに保存して、後でデータを送信したりできます。

private static void onAccept(IAsyncResult ar)
{
    Socket clientSocket = ((Socket) ar.AsyncState).EndAccept(ar);

    // begin to accept the next client connection
    _socket.BeginAccept(onAccept, _socket);

    // this is the socket you can send data to the connected client:
    clientSocket.Send(data);
}

TCPアプローチには、接続されたクライアントがあり、サーバーが接続されたクライアントの数を認識している場合にのみサーバーがデータを送信するという利点があります。

于 2011-10-25T15:18:26.410 に答える
1

TCPを使用する場合、を呼び出す必要はありませんが、を呼び出すBind()必要がありますConnect()

_socket.Connect(endPoint);

これは、コード内に接続先のローカルネットワーク_localIp上のIPアドレスであり、接続に使用するローカルコンピューター上のネットワークアダプターのIPアドレスではないことを前提としています。

Bind()ソケットをローカル(つまり、現在のコンピューター上)のエンドポイントにバインドします。使用されているネットワークアダプタを気にせず(つまり、ターゲットIPに基づいてシステムに決定させる)、使用されているローカルポートも気にしない場合は、を呼び出す必要はありませんBind()

于 2011-10-25T15:05:20.717 に答える