1

我有以下设置:

服务器将通过蓝牙连接到发送离散信号的多个设备。然后会有 n 个客户端可以查询服务器(可能通过 Web 服务)连接了哪些设备并收听来自他们想要的设备的信号。

我认为最好的实现方式是:当服务器通过 BT 连接到设备时,它会打开一个 Socket 到本地端口并将数据发送到那里。当客户端请求可用设备时,服务器将返回一个字典,然后客户端只需要监听该端口。

但是我在套接字实现方面遇到了一些问题。如何创建信号并将其写入本地端口?

这是我到目前为止得到的:

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

使用 TCP 时,不需要调用Bind(),但需要调用Connect()

_socket.Connect(endPoint);

这假定在您的代码_localIp中是您要连接到的本地网络上的 IP 地址,而不是您要用于连接的本地计算机上的网络适配器的 IP 地址。

什么Bind()是将套接字绑定到本地(即在当前计算机上)端点。如果您不关心使用什么网络适配器(这意味着您让系统根据目标 IP 来决定),并且您也不关心使用什么本地端口,则无需调用Bind().

于 2011-10-25T15:05:20.717 回答
1

您可以使用 UDP 广播,因为评论建议您不必建立连接。服务器只在一个端口上发送数据,任何感兴趣的客户端都可以在该端口上接收该数据。

如果您想区分您的设备,您可能必须在单独的端口上广播每个设备的数据。当您拥有许多设备时,这可能是很多(不必要的)网络流量。

另一种选择是使用 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 回答