Micropython python-socket

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Micropython python-socket

Inlägg av sodjan »

Och hur var det med fenomenet i första inlägget?
Nerre
Inlägg: 26655
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Micropython python-socket

Inlägg av Nerre »

Min gissning är bristfällig implementation.

Jag grävde mycket i detta för typ 100 år sen (eller nåt, början av 90-talet måste det varit) när jag hade planer för att försöka fixa till min SVI-328 (med Super Expander) för Packet Radio. Jag tittade på hur man eventuellt skulle kunna använda Z80 SIO för detta.
guckrum
Inlägg: 1671
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Micropython python-socket

Inlägg av guckrum »

Hmm, TCP/IP (om det är det som används) är ju mellan två par av IP-adress+port (RFC 793). Ett interface kan ju ha flera IP-adresser samtidigt. Och många portar. Så det är ju viktigt att paketen "hamnar rätt", dvs på rätt adress och på rätt port. Annars kan ju vad som helst hända.
agehall
Inlägg: 418
Blev medlem: 12 augusti 2020, 19:27:54

Re: Micropython python-socket

Inlägg av agehall »

sodjan skrev: 29 januari 2023, 18:16:26 Hur som helst, vi halkade in i det här träsket efter att du skrev:
"Är det en IP-adress som klienten har tar den emot paketet, annars skickar den det vidare (det är detta som är routing)."

Det låter som att det alltid är så, vilket som sagt är totalt fel. Det är i princip bara burken som är en "router" som gör det.
Nja, det är flera fel med det där. Routing är det som sker när en enhet fattar ett beslut om vilket interface ett utgående paket ska skickas på. Forwarding är när det avgörs om paketet ska skickas via.

De flesta större TCP/IP implementationer (dvs Windows, Linux, MacOS, BSD etc etc) kan göra både routing och forwarding. Mindre stackar som vi ofta springer på i MCU-sammanhang är det inte lika självklart. Däremot är det inte säkert att ett OS per default skickar paket vidare mellan interface även om det har stöd för det. Ta tex en standard Linux - där måste du själv slå på IP-forwarding om du vill att maskinen ska kunna skicka paket vidare.


Om vi återgår till ditt problem så låter det helt klart som att du vid något tillfälle råkar få två olika DHCP-servrar på samma nät. Det är något man inte ska ha om man inte vet vad man gör och varför man vill ha det. Troligen är det väl din MCU som drar igång en server vid något tillfälle och samtidigt råkar din server be om att få sin IP-adress förnyad varpå MCU:n svarar före din router. Lösningen här är ju uppenbarligen att se till att din MCU aldrig startar en DHCP-server.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Micropython python-socket

Inlägg av Oltronix »

Svårt att felsöka när det inte går att skapa fel på beställning utan de är intermittenta och väldigt ovanliga. ESP-kraften kommer från en version 3 USB-hub, Plexger, som jag numera matar med extern kraft 5V/2A . Så jag antar att krafförsörjning är bättre nu. Skall senare ta bort externa kraftmatningen och antar att jag kommer återfå ett antal skumma fel. Just nu har jag två återkommande fel men sällsynta.

1. "OSError [Errno 110] Connection timed out" vilket jag hanterar i koden och kommunikation återstartar efter 2-6min.

2. "OSError [Errno 103] ECONNABORTED". Som jag inte har löst. På kliensidan hänger koden på läsistruktion. "s.recv(102)"
Var på serversidan koden är vet jag inte men det blir exception. (jag gissar, obs! gissar att koden fastnar på "s.accept()"
Om det är så så blir det något deadlock-liknade. En process väntar på data den andra väntar på ett connect()-anrop.

netstat ger samtidigt följande vid [Errno 103]:
erik@HP:~$ netstat -np| grep 65432
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.1.132:50986 192.168.1.176:65432 ESTABLISHED 3248/python3

3. Övrigt, jag får tcp-fel enligt Wireshark men dessa kan jag inte relatera till andra händelser.

4. Med nestat ser jag ett antal tcp-state:
  • FIN_WAIT1 - , FIN_WAIT2, SYN_SENT, -ESTABLISHED 29393/python3

och ibland flera state stamtidigt:
  • tcp 0 0 192.168.1.202:49150 192.168.1.176:65432 FIN_WAIT2 -
    tcp 0 1 192.168.1.202:48648 192.168.1.176:65432 FIN_WAIT1 -
    tcp 0 1 192.168.1.202:49156 192.168.1.176:65432 SYN_SENT 24511/python3
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Micropython python-socket

Inlägg av Oltronix »

Jag skall nog hacka om det jag gjort. Jag hanterat det som fanns två synkrona processer. Det blir väldigt asynkront spec när det händer saker på TCP-nivån eller andra varandra oberoende prosesser. Det finns threads och kanske sofware-timers mm sånt som jag inte har kunskap om, ännu.
Dessa fel får jag från servern:
  • [Errno 98] EADDRINUSE
    [Errno 103] ECONNABORTED
    [Errno 104] ECONNRESET
Error 98, är när programmet startar och info om gammal socket finns kvar. HW-reset löser detta. SW-rest räcker ej.
Klienten:
  • [Errno 101] Network is unreachable
    [Errno 104] Connection reset by peer
    [Errno 110] Connection timed out
    [Errno 113] No route to host
Error 104, Hittade följande beskrivning, "Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur"

Jag tycker detta är spännande:
  • Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 192.168.1.202:49150 192.168.1.176:65432 FIN_WAIT2 -
    tcp 0 1 192.168.1.202:48648 192.168.1.176:65432 FIN_WAIT1 -
    tcp 0 1 192.168.1.202:49156 192.168.1.176:65432 SYN_SENT 24511/python3
3 socket aktiva samtidigt. 1.202 är klienten. 1.176 severn.

Det mest spännande är detta på klientsidan:
  • 891 OSError [Errno 104] Connection reset by peer
    b'dataEmpty' 08:10:12.798355
    Taxi Stockholm - alltid pålitliga.892 OSError [Errno 104] Connection reset by peer
    b'dataEmpty' 08:10:20.848127
Jag hade samtidigt en sida i Firerfox öppen "dn.se" med en annons på sidan med texten "Taxi Stockholm - alltid pålitliga". Snacka om TCP-problem. Jag trodde TCP-stacken i ubuntu var ordentligt avslusad. Allt annat förutom meningen om Taxi är förväntad data. Detta har bara hänt en gång. Vad jag vet.

(jag har funderat om man skall tänka på en socket som en process? De skapas och sedan dör)
Senast redigerad av Oltronix 2 februari 2023, 18:15:33, redigerad totalt 1 gång.
Nerre
Inlägg: 26655
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Micropython python-socket

Inlägg av Nerre »

guckrum skrev: 29 januari 2023, 21:55:53 Hmm, TCP/IP (om det är det som används) är ju mellan två par av IP-adress+port (RFC 793). Ett interface kan ju ha flera IP-adresser samtidigt. Och många portar. Så det är ju viktigt att paketen "hamnar rätt", dvs på rätt adress och på rätt port. Annars kan ju vad som helst hända.
Paketen skickas ju förpackade i Ethernetframes mellan nätverkskorten, sen är det ju tcp/ip-stacken som tar hand om vad som händer med IP-paketen. Ett IP-paket har såvitt jag minns ingen port utan bara en typ.
agehall
Inlägg: 418
Blev medlem: 12 augusti 2020, 19:27:54

Re: Micropython python-socket

Inlägg av agehall »

Korrekt. Port är ett påfund på högre nivå. Typiskt sett är det UDP och TCP som använder portar men det kan förekomma i andra protokoll också. IP-nivån är helt ovetande om portar.

Att ha en massa hängande TCP-koppel i sin nätverksstack är mer regel än undantag om man inte själv tweakat en massa inställningar. Om du inte kör en extremt populär webbsida (tänk aftonbladet.se) så är det inte något du behöver bry dig om utan det är bara att ignorera. Det är dock lätt att bli förvillad om man läser teorin och tror att allt ska fungera så i praktiken.

Utan att se hela koden så tror jag detta bara kommer ge gissningsleken när det gäller att klura ut exakt vad som är fel - jag tycker det känns som att din klient kör en DHCP-server (vilket den inte borde göra) men det är svårt att säga med säkerhet utan att se all kod.
guckrum
Inlägg: 1671
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Micropython python-socket

Inlägg av guckrum »

För mig är det hela lite suddigt. Skulle du kunna beskriva hur din setup ser ut idealt sett?

Jag gissar:
- att du har en linuxburk uppkopplad enbart på Wi-Fi mot en accesspunkt som via DHCP ger den ett IP-nummer (192.168.1.176). Antar 8-bitars netmask.
- att din ESP också skall vara uppkopplad mot samma Wi-Fi-accesspunkt och få ett IP-nummer i samma subnät?

Det spekulerats också i tråden att din ESP *även* driver subnät 192.168.4.x med DHCP-server (också här antar jag 8-bitars netmask), och därmed också (?) har en IP-adress i detta nät.

Om man kollar lite i dina loggar så ser man att din ESP får lite olika IP-nummer: .202 och .132. Kanske skulle ändra till "statisk DHCP" om din accesspunkt supportar det, för att eliminera så mycket källor till strul som man kan från felsökningen.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Micropython python-socket

Inlägg av sodjan »

Om sedan denna ESP och linux-burken ska kommunicera direkt med varandra
så är det väl väldigt opraktiskt om båda har en dyn-DHCP adress?
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Micropython python-socket

Inlägg av Oltronix »

Jag trodde någon skulle reagera på "Taxi Stockholm - alltid pålitliga" i mitt förra inlägg. Det tyckte jag var spännande.

Mitt mål är att läsa data från server 1ggr/min. Ibland mycket fortare. Jag vill inte skriva fil på flash. Hur jag skall hantera filer i RAM vet jag ej.
Ett sätt är att anvånda "wget"-kommandot men för att slippa strippa massa html-taggar så tänkte jag att socket skulle var det rätta. Det är kanske fel.

Serverurl: 192.168.1.176. Klienturl:192.168.1.202

Serverkoden kommer från micropython dokumentation. https://docs.micropython.org/en/latest/ ... k_tcp.html Kap 5.1 och 5.2. Klientkoden kommer från https://realpython.com/python-sockets/. Koden som jag har är ett hack av dessa orginal. Jag inte är spec stolt över den, kanske därför har jag inte meddelat den.
Serverkod:

Kod: Markera allt

ver="""2023-01-30"""
print('ver:', ver)
import ds
roms=ds.scan()

import socket
addr = socket.getaddrinfo('0.0.0.0', 65432)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1) 

while True:
    try:
       cl, addr = s.accept()
       print('client connected from', addr)
       cl_file = cl.makefile('rwb', 0)
       t = ds.read4(roms)
       arr = bytes(str(t[0]), 'utf-8')
       cl.sendall(arr)
       cl.sendall(b' ')
       arr = bytes(str(t[1]), 'utf-8')
       cl.sendall(arr)
       cl.sendall(b' Send#2')
    except OSError as e:
       print('OSError A', e:
    except Exception as e:
       print('Exception', e)
        
    while True:
        try:
           line = cl_file.readline()
           print('line:', line)
           if not line or line == b'\r\n':
               print('empty line break:') 
               break
        except OSError as e:
           print('OSError B', e)
           break
    arr = bytes(str(t), 'utf-8')
    print(arr)    #Varför kommer inget till klienten här?
    try:
        cl.sendall(b'Send#3')
        cl.close()
    except OSError as e:
        print('OSError C', e)
    finally:
       cl.close()       #Det fungerar att göra close() fler ggr! 
Klient:

Kod: Markera allt

  import socket
import time
import datetime

now = datetime.datetime.now()
print(now.time())

addr=(('192.168.1.176', 65432))

I=0
while True:
    print(I, end=' ')
    arr = bytes(str(I), 'utf-8')
    s = socket.socket()
    data=b'dataEmpty'  #So data exist if exception. OSError [Errno 110] Connection timed out. Borde fixas med exception istället

    try:
       s.connect(addr)
       s.sendall(b'---  Euuuurik -------')
       s.sendall(arr)
       data = s.recv(1024)
       time.sleep(4)
    
       s.close()
    except OSError as e:
       print('OSError', e)
       s.close()
    except Exception as e:
       print('Exception', e)
       
    data=str(data)
    print(data, end=' ')
    now = datetime.datetime.now()
    print('\t',now.time())
    I +=1
    time.sleep(5) 
Är det några fler utestående frågor?
//Erik
Ps Tack för all energi ni lagt ner på detta!
Skriv svar