Weird behavior from either TcpClient or network

Viewed 100

So I have two smartbulbs from Yeelight. I am trying to turn them on/off at the same time. You can achieve that by sending some TCP messages to them. This works completely fine from NodeJS with this little script:

const net = require("net")

send_to_lamp("192.168.178.83", '{"id": 1, "method": "set_power", "params": ["on", "sudden"]}\r\n', answ => console.log(answ))
send_to_lamp("192.168.178.84", '{"id": 1, "method": "set_power", "params": ["on", "sudden"]}\r\n', answ => console.log(answ))
console.log("sent")

function send_to_lamp(ip, body, callback) {
    var con = net.createConnection({port: 55443, host: ip}, () => {
            con.write(`asd\r\n`) // send two requests to wake up connection
            con.write(body)
    })
}

But now comes the weird behavior to play: When trying to do the exact same thing from C#, only the first bulb that is contacted reacts to the message. For example when executing this code:

using System.Net.Sockets;

Thread t1 = new Thread(con1);
t1.Start();
await Task.Delay(1000);
Thread t2 = new Thread(con2);
t2.Start();
await Task.Delay(5000);

async static void con1() {
    await TryConnect("192.168.178.83", "{\"id\": 1, \"method\": \"set_power\", \"params\": [\"on\", \"sudden\"]}\r\n");
}

async static void con2() {
    await TryConnect("192.168.178.84", "{\"id\": 1, \"method\": \"set_power\", \"params\": [\"on\", \"sudden\"]}\r\n");
}

static async Task TryConnect(String server, String message)
{
  try
  {
    using (var client = new TcpClient()){
        await client.ConnectAsync(server, 55443);
        using (var netstream = client.GetStream()) 
        using (var writer = new StreamWriter(netstream))
        using (var reader = new StreamReader(netstream))
        {
            writer.AutoFlush = true;
            netstream.ReadTimeout = 3000;
            await writer.WriteLineAsync(message);
            Console.WriteLine("sent {0}", message);
        }
    }
  }
  catch (ArgumentNullException e)
  {
    Console.WriteLine("ArgumentNullException: {0}", e);
  }
  catch (SocketException e)
  {
    Console.WriteLine("SocketException: {0}", e);
  }
}

Only the lamp with the IP 192.168.178.83 turns itself on. It even gets weirder. When just swapping the IP in the both con1/2 functions, so that the lamp with the IP 192.168.178.84 is called first, only it reacts and the lamp with the IP 192.168.178.83 does nothing. I tried several different methods of sending TCP messages from C# (using async, multi-threading, have a dedicated class for each TcpClient ...)

Anyone got an idea what I can try to get this to work?

Wireshark log during NodeJS script

Wireshark log during C# script

Disclaimer: I do not know much about TCP connections and how they should look in Wireshark, but just seen from the software side of things this really seams nonsensical.

1 Answers

In the C # log you have RST because there you are using using which automatically closes the TCP connection. In Node.js, you would probably have to trigger the connection to close manually.

It's best to test your application using a TCP terminal (https://www.hw-group.com/software/hercules-setup-utility). Use it to create a local TCP server with listening port 55443.

Example settings

Now in your C # application refer both to IP 127.0.0.1 and change the transmitted content to distinguish between frames. For example, for the second lamp, set "id": 2.

This way you will see if your application is establishing a connection correctly and if the transferred data is complete.

Related