Ubuntu: Pipe raw unbuffered data to TCP port - linux

My overall goal:
I have a hardware device that streams sensor data to a Ubuntu laptop running a Python script. Data comes in chunks of 240 samples (one per line with \n) every 2 seconds and prints to stdout. I start the Python script on the Ubuntu laptop and pipe its output to a TCP port using netcat. I connect to that TCP port from any other device on the network and get the live data stream - without first loading all previous samples.
My Setup:
Two laptops.
1: Ubuntu collects readings from a sensor, and pipes those readings to TCP port 1234.(This is working.) $ py read_sensors.py | nc -lk 1234
2: Windows 10, has WSL, Python, and existing scripts for processing data streamed from the first laptop. (This is working in WSL) $ nc 10.10.10.01 1234
My Problem:
I begin streaming sensor data on the Ubuntu laptop.
10 min later I connect to that stream from my windows laptop...
I expect to receive the most recent sample at the time the connection was established, and all subsequent samples in (pseudo) real-time.
Instead, as soon as I connect I am flooded with all samples collected since I began the streaming pipeline on the Ubuntu laptop, and once it catches up, I start seeing real-time data.
I have tried: Searching led me to try stdbuf. Lack of results led me to try various combinations of $ stdbuf -oL py read_sensors.py | nc -lk 1234 $ py read_sensors.py | stdbuf -oL nc -lk 1234 but every time I wait a little bit then connect to the port from my windows laptop, it loads all samples from the time I started streaming on the Ubuntu laptop.
I assume: This is a buffering issue and that it will have to be fixed on the Ubuntu machine - but the various combinations of stdbuf has not had any effect on the behavior of the system. So, I turn to the SO gods for insight and grace :)
-Nick

Something like this might meet the overall goal. Based on https://docs.python.org/3/library/socketserver.html#socketserver-tcpserver-example
import socketserver
class MyHandler(socketserver.BaseRequestHandler):
def handle(self):
bytes = read_sensor_data() # call the code that reads the sensors
self.request.sendall(bytes)
if __name__ == "__main__":
with socketserver.TCPServer(("localhost", 1234), MyHandler) as server:
server.serve_forever()

Disable netcat buffering:
Force netcat to send messages immediately (without buffering)
Alternately, I believe if you use bash’s built in tcp connections bypassing netcat, it will work. E.g. read_sensors.py > /dev/tcp/10.10.10.1/1234
EDIT: Added sample code that shows how to send and receive.
Example code:
To send:
#!/bin/bash
while true
do
date > /dev/tcp/localhost/1234 || true # replace date command with read_sensors.py
sleep 1
done
to receive:
ubuntu#ubuntu:~$ nc -lk 1234
Output:
Tue Mar 2 20:40:24 UTC 2021
Tue Mar 2 20:40:25 UTC 2021
Tue Mar 2 20:40:26 UTC 2021
Tue Mar 2 20:40:27 UTC 2021
^C
ubuntu#ubuntu:~$ nc -lk 1234
Tue Mar 2 20:40:40 UTC 2021
Tue Mar 2 20:40:41 UTC 2021
Notice 13 second gap while I hit control C, no data sent or buffered up.

Related

Is there a way to monitor and create a log file for my internet connection in Linux Mint 19.3 for a Time interval?

I'm experiencing some problems with my internet connection so my provider told me to make a logfile for an evening (min. 3 Hours) to see when the connection drops out to see what's the cause of the problem.
When I'm losing connection, I still remain in the network but my Inernet is simply 0B/s. Is there a way to make a log for a certain Time interval that constantly checks the internet connection (and ideally the download/upload speed). I'm kinda beginner in the Linux world and it would be very helpful when the answer will be good explained and every step will be described.
Thanks in advance.
For checking every 10 seconds that your connection is available you could use
ping 8.8.8.8 -D -i 1 2>&1 | tee my.log
where 8.8.8.8 is a DNS server run by Google.
File my.log will receive entries like:
[1583495940.797787] 64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=17.9 ms
[1583495950.809658] 64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=18.7 ms
ping: sendmsg: Network is unreachable
The number in square brackets is the time in seconds since 1970-01-01T00:00:00Z. For our example:
1583495950 = 2020-03-06T11:59:10Z
If you want to really transfer data, you could use a script like:
#!/bin/sh
URL=https://example.com
while [ true ]
do
wget $URL -O /dev/null 2>&1 | grep 'saved' | tee my.log
sleep 10
done
But mind the traffic cost on both sides.

Cant receive Hex response from Imatic board

Good day,
This is going to be long. I'm trying to communicate with the "SainSmart iMatic with RJ45" board, which is used together with the "SainSmart 16-Channel 12V Relay Module".
Basically, I'm able to send hex commands to the board, successfully, but can't receive a response from the board when required. What do I mean with this?
I have a laptop with Ubuntu 14.04.4 LTS connected directly to the board via an Ethernet Straight through cable (no longer crossover type needed). I have a configuration for this type of network (only two devices). The IP of the imatic board is fixed, 192.168.1.4 with port 3000. My laptop IP has a fixed IP of 192.168.1.2, with netmask 255.255.255.0, and no gateway.
I'm using netcat (in TCP protocol mode) in my laptop to send commands to the board in this format in terminal :
echo '580112000000016C' | xxd -r -p | nc 192.168.1.4 3000
How do I know it works? Well, basically the relays from a secondary board are turned on successfully ("SainSmart 16-Channel 12V Relay Module").
There's a list of hex commands to turn on and off each relay. In the previous instruction, I'm telling the board to turn on the relay number 1, leaving the other 15 off. The string '580112000000016C' is converted from hex into binary with xxd, and then sent into the netcat. This part works.
The only instruction that doesn't work is this one:
echo '580113000000006C' | xxd -r -p | nc 192.168.1.4 3000
This instruction only asks the board which relays are off an on at the moment, expecting a response in this format:
28 01 00 00 00 XX XX HH (XX XX 16 bit, each bit represents one relay state, "1" indicates on, "0" indicates OFF; HH is the sum of all previous data together, meaning it works as a checksum)
I've already tested and proved that, this is NOT an issue from the board. I wrote a code in visual basic, and windows was able to receive the response from the board, but something has to be wrong in my ubuntu configuration.
I've already disabled my firewall, ufw.
This is NOT a problem with the Ethernet cable.
I've already tried other command representations such as:
echo -n '5801100000000069' | xxd -r -p | nc -v -n -w3 192.168.1.4 3000 | xxd
I've already used netcat to scan all available ports in the board, and only the 3000 port is shown as available, as stated from the manufacturer.
This seems to be a network configuration problem though, but in windows, I specified the same IP, and netmask as in ubuntu.
What am I mising here?
Netcat is waiting for an EOF character, which is never sent by the iMatic board. That explains why netcat can't receive the response ever.
On the other hand, I wrote a python script (Python 2.7.6) which successfully receives the data from the iMatic board, after sending to it a certain instruction. Here it is:
import socket
import binascii
IPADDR = '192.168.1.4'
PORTNUM = 3000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IPADDR, PORTNUM))
data = '5801100000000069'.decode('hex')
s.send(data)
response= s.recv(8) #Buffer needs to be 8 for the fastest response without losing information
print binascii.hexlify(response)
s.close()
You can use this board now without a router, and directly connected to any computer through an Ethernet cable.
Regards,
Bernext.

Jmeter running in Linux command not returning correctly

I am trying to run a fairly large monitoring test in jmeter through Linux.
The .jmx file I am using runs and keeps the test running on an infinite loop when run on a GUI version of Jmeter.
To run it on Linux I am using :
sh jmeter.sh -n -t MasterMonitorNew.jmx -l log.jtl
but the response I get from the test is:
Creating summariser <summary>
Created the tree successfully using MasterMonitorNew.jmx Starting the
test # Sun Feb 08 18:49:14 EST 2015 (1423439354371)
Waiting for
possible shutdown message on port 4445
summary = 0 in 0s = ******/s Avg: 0 Min: 0 Max: 0 Err: 0 (0.00%) Tidying up ... # Sun Feb 08 18:49:14 EST 2015 (1423439354658) ... end of
run
The entire test takes less then 2sec till it shuts itself off, any help would be much appreciated.

How can I limit pppd record file size?

My mother tongue is not English, sorry for my English.
I use pppd with a GPRS module.
I use like pppd record record.pcap call tdscdma command to access Internet.And pppdump record.pcap or wireshark to show the record.pcap.
when pppd run ,the record.pcap will save all data and the file size getting bigger and bigger.
Now I am just want save last(Newest) 1Mb(for example,or quantity) message.And how can I limit the file size.
I am more concerned about the recent network conditions. FIFO is not necessary.if the file bigger than 1Mb, truncate it to zero is OK too.
[root#AT91SAM9-RT9x5 logs]# pppd -v
pppd: unrecognized option '-v'
pppd version 2.4.5
[root#AT91SAM9-RT9x5 logs]# uname -a
Linux AT91SAM9-RT9x5 2.6.39 #34 Wed Jun 4 16:12:41 CST 2014 armv5tejl GNU/Linux
Use wireshark looks like this:
Can you use tcpdump program for capturing traffic of ppp0 interface?
There are -C and -W options for limiting size of output files.
Example:
tcpdump -i ppp0 -C 1 -W 2 -w file.pcap
See more from man page: tcpdump(8).

How do I log data from my serial ports consistently?

I need to deal with two pieces of custom hardware which both send debugging data over two serial connections. Those serial connections go through two serial-to-USB converters. The serial-to-USB devices have the same vendor numbers, device numbers, and, apparently, the same serial numbers.
Here's the issue: I want to log the two serial ports separately. The custom hardware needs to be rebooted constantly, and whether they attach to the same /dev/ttyUSB* is completely random. How can I make them pick the same device path every time? I could make it dependent on what port it is plugged into, but that seems kind of hacky.
So, I ran a diff against the output of udevadm, like so:
$ udevadm info -a -p `udevadm info -q path -n /dev/ttyUSB1` > usb1
$ udevadm info -a -p `udevadm info -q path -n /dev/ttyUSB2` > usb2
$ diff usb1 usb2
The output of the diff is long; you can see it here
Grepping for serial (same for both):
$ udevadm info -a -p `udevadm info -q path -n /dev/ttyUSB2` | grep serial
SUBSYSTEMS=="usb-serial"
ATTRS{serial}=="0001"
ATTRS{serial}=="0000:00:1d.7"
Other info:
I'm using PuTTY to read from the serial ports.
OS:
$ uname -a
Linux xxxxxxxx.localdomain 2.6.32-279.14.1.el6.x86_64 #1 SMP Tue Nov 6 23:43:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Please check if the usb-serial converter is based on a ftdi chip?
(You can check driver filenames)
If so; you have a chance to change serial number,or even the manufacturer info.
http://www.ftdichip.com/Support/Utilities.htm
Check the tools; MProg and FT_PROG utility tools.

Resources