C# 局域网环境下的Socket通信

C# 局域网环境下的Socket通信,c#,tcpsocket,C#,Tcpsocket,我有以下设置: 服务器将通过蓝牙连接到发送离散信号的多个设备。然后,将有n个客户端可以查询(可能通过web服务)连接了哪些设备的服务器,并侦听来自所需设备的信号 我认为实现这一点的最佳方式是:当服务器通过BT连接到一个设备时,它将打开一个到本地端口的套接字并将数据发送到那里。当客户端请求可用设备时,服务器将返回一个字典,然后客户端只需侦听该端口 但是我在套接字实现方面遇到了一些问题。如何创建信号并将其写入本地端口 到目前为止,我得到的是: class Device { ... p

我有以下设置:

服务器将通过蓝牙连接到发送离散信号的多个设备。然后,将有n个客户端可以查询(可能通过web服务)连接了哪些设备的服务器,并侦听来自所需设备的信号

我认为实现这一点的最佳方式是:当服务器通过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(即数据)时;我收到以下例外情况:

不允许发送或接收数据的请求,因为套接字未连接,并且(使用sendto调用在数据报套接字上发送时)未提供地址


这是正确的方法,但需要有人连接到套接字才能读取数据吗?

使用TCP时,您不需要调用,但需要调用

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


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

您可以使用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方法的优点是,只有当存在已连接的客户端并且服务器知道已连接的客户端数量时,服务器才会发送数据。

正如错误所述-套接字没有连接。。。您希望套接字对您发送的数据做什么?缓冲?丢弃它?数据将是实时的,所以我希望任何想要读取数据的客户端只需连接到该端口并读取那里写入的内容。我不知道TCP套接字是否是最好的方法,但我希望类似于在线流媒体。如果数据丢失是可以接受的,我强烈建议UDP广播(即“无连接”)-它的工作原理更像一个“收音机”,任何想要收听的人只需要知道要收听的端口…是的,或者使用UDP,正如Yahia所说,这是一个无连接协议;或者,您可以将数据缓冲在MemoryStream(或其他缓冲机制)中,然后在客户端连接时发送数据。如果你想在收到BT数据后立即“发送并忘记”,那么我认为UDP是最好的选择。谢谢@Yahia和Parmenion,我将阅读一些关于UDP广播的文档并尝试一下。localIp是本地计算机ip。我使用bind()在当前计算机上分配一个空闲端口。我不在乎使用哪个端口,我只想要一个免费端口将数据发送到那里,以便其他计算机能够获取数据。我想区分设备,但最坏的情况是7,因为BT不允许更多连接。TPC方法似乎足够简单。
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);
}