[Solved] Data over UTP cable

Context: am doua microcomputere (raspberry și un upboard). Unul face ceva procesare și trebuie să ii trimită celuilalt informații (string, json, oricum). Le voi monta undeva unde nu am conexiune internet și sunt curios: pot trimite informații între dispozitive dacă le leg cu un cablu utp?

Am reușit cu doua raspberry conectate la rețeaua locală și python socket. Una ascultă, cealaltă trimite hostname-ului primei cutii. Dar nu pot să fac același lucru cu jucăriile în afara unei conexiuni de rețea.

E fezabil ce vreau eu să fac aici?

server.py

import socket
import threading
import json


class ServerSocket:
    def __init__(self, port):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.port = port
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.s.bind(('', self.port))

    def handle_cli(self, client_socket):
        request = client_socket.recv(1024)
        data = json.loads(request.replace("'", '"'))
        print data

        client_socket.send('ACK!')
        client_socket.close()

    def listen(self, max_connections):
        self.s.listen(max_connections)
        while True:
            c, addr = self.s.accept()
            client_handler = threading.Thread(target=self.handle_cli, args=(c,))
            client_handler.start()


try:
    main_socket = ServerSocket(12345)
    main_socket.listen(5)

except Exception as main_sock_err:
    print 'main_sock_err', main_sock_err

client.py

import socket, sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = 'raspberry.local'
# port = int(sys.argv[1])

s.connect((host, 12345))
s.send('{"data":"here"}')

if s.recv(1024) == "ACK!":
    # all good
    pass

nu ca m-as pricepe cine stie ce la retelistica, dar cred ca ai avea nevoie de un switch !

In mod ironic e extrem de simplu.

Conectezi cele 2 cu un cablu utp normal, setezi un ip din aceeasi clasa gen 10.0.0.1 si 10.0.0.2.

sudo ip ad add 10.0.0.1/24 dev eth0
si pe celalalt
sudo ip ad add 10.0.0.2/24 dev eth0

(netmask-ul e 255.255.255.0)

Daca dai ping intre calculatoare ar trebui sa mearga, vezi sa nu iti blocheze porturile o regula din iptables.

Foloseste websockets cu uws.

1 Like

In principiu da. Iti trebuie un cablu crossover atunci cand legi doua calculatoare intre ele. Daca nu gasesti de cumparat, poti sa faci si singur oarecum, deoarece e doar o chestie de aranjare a celor 8 fire din cablul de ethernet non-fibra.

Ping&friends ar trebui sa mearga si interfetele sa apara ca “up”, eventual si cu luminitele aferente.

2 Likes

Different type of sockets.

Este destul de probabil ca mai toate echipamentele recente sa fie dotate cu interfete ethernet cu Auto MDI-X si sa mearga si cu patch-uri obisnuite.

Edit: daca ai net-tools instalat poti sa verifici simplu daca link-ul fizic este “up”, output-ul arata cam asa:

mii-tool eth0
eth0: negotiated 1000baseT-FD flow-control, link ok
2 Likes

Da, toate placile de retea din ultimii 10 ani merg fara un cablu crossover.

Atentie foarte mare cum lucrezi cu sockeţii. Nimeni si nimic nu garanteaza ca toate datele sosesc “dintr-o bucata”, chiar daca teoretic viteza de transmisia este extrem de mare. Din diverse motive, pachet-ul de date poate sosi pe bucăţi, chiar octet cu octet. Întotdeauna să pleci de la premiza asta. Sunt doua tipuri de rezolvari:

  1. Inainte sa trimiti datele sa trimiti un header (sa zicem din 4 octeţi, little-endian) în care se specifică cantitatea de date pe care urmeaza s-o receptionezi. Astfel poti sa executi read() pana primesti tot.

  2. Folosesti un terminator oarecare. Asta e buna pentru date de tip text, de exemplu executi read() pana dai de terminatorul zero (sau ce vrei tu si care nu e posibil sa apara si in datele utile).

Şi încă ceva, din diverse motive conexiunea se poate “agăţa” (aia TCP in special) şi trebuie sa-ţi laşi o portiţă de scăpare din situatia asta. Din acest motiv eu intotdeauna folosesc sockeţi non-blocanti si select() sau poll() sau epoll(). Atunci când conexiunea s-a agăţat in timp ce esti in bucla de read() select-ul (daca e setat corespunzator) pur si simplu va da timeout la citire si vei putea iesi din bucla si sa afisezi userului un mesaj de eroare in care explici ce s-a intamplat.

3 Likes

Yup, trebuia sa dau un disclaimer: cunostinte vechi de peste 10 ani :frowning:

Hehe, cum am luat şi eu ţeapă cu SNI, dezavantajul de a fi bătrân :slight_smile:

1 Like

Am găsit asta și cred că o sa îmi explice bine ce mi-ai recomandat. Merci de pont.

Am sa încerc cum m-ați sfătuit, revin cu un status de mâine.

Rezolvat: pe Upboard ruleaza ubuntu 16, acolo am facut setarea de internet pentru ‘wired connection’ din GUI: adresa 10.0.0.2, netmask 24.

Pentru Raspberry ,unde rulez raspbian lite, am adaugat o regula nou in /etc/rc.local : ip a add 10.0.0.1/24 dev eth0.

Cablul folosit nu este crossover, dar poate am sa fac unul daca este de preferat asa.

Toate-s bune acum!

Merci!

1 Like