Search code examples
c#tcpsocket

Socket communication on a LAN environment


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?


Solution

  • 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.