LAN环境下的Socket通信

发布于 2024-12-11 16:53:56 字数 914 浏览 0 评论 0原文

我有以下设置:

服务器将通过蓝牙连接到发送离散信号的多个设备。然后将有 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 调用在数据报套接字上发送时)未提供地址

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

I have the following setup:

The server will connect via Bluetooth to several devices that are sending a discrete signal. Then there will be n clients that can inquiry the server (via web services probably) for which devices are connected and listen to the signal from the devices they want.

I think the best way to implement this is: when the server connects to a device via BT, it will open a Socket to a local port and send the data there. When a client ask for the available devices, the server will return a Dictionary and then the client just have to listen to that port.

But i'm having some problems with the socket implementation. How can I create and write the signal to a local port?

This is what I got so far:

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);
    }
}

But when reaching the _socket.Send(e.Data); I receive the following exception:

A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

Is this the right approach but it needs to have someone connected to the socket to read the data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦归所梦 2024-12-18 16:53:56

您可以按照注释建议使用 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 方法的优点是您的服务器仅发送数据当有连接的客户端并且您的服务器知道连接的客户端数量时。

You can use UDP Broadcast as the comments suggest where you don't have to establish a connection. The server justs sends the data out on one port and any interested client can receive that data on that port.

If you want to distinguish between your devices you might have to broadcast every devices data on a separate port. That might be a lot of (unnecessary) network traffic whn you have many devices.

The other option is using TCP.
Your server as to listen for incoming connections from your clients:

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

In onAccept you have access to the clientsocket and can send data or store the reference to the socket somewhere to send data later on:

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);
}

The TCP approach has the advantage that your server only sends data when there are connected clients and your server is aware of the number of clients connected.

静待花开 2024-12-18 16:53:56

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

_socket.Connect(endPoint);

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

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

When using TCP, you don't need to call Bind(), but you need to call Connect().

_socket.Connect(endPoint);

This assumes that in your code _localIp is an IP address on the local network you want to connect to and not an IP address of a network adapter on the local computer that you want to use for the connection.

What Bind() does is to bind the socket to a local (i.e. on the current computer) end point. If you don't care what network adapter is used (which means you let the system decide that based on the target IP), and you also don't care what local port is used, there is no need to call Bind().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文