Forum >> Principianti >> Utilizzo Socket

Pagina: 1 2 3 4 5 Avanti

Credo di aver letto tutto quello reperibile in rete sui Socket

Gira che ti giro è sempre quello

Io ho implementato questo

*****************

serverName = "127.0.0.1"
serverPort = 8000
# create TCP socket
terminale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect socket to remote server at (serverName, serverPort)
terminale.connect((serverName, serverPort))

terminale.sendall(request)
print("FINE TRASMISSIONE")

data = ""
while len(data) > 0:
data = terminale.recv(2048 ) #lo spazio fra l'8 e la parentesi è aggiunto perchè altrimenti diventa una faccina :dont-know:
data = data + data

print( "ricevuto: ", data)
zzz = len(data)
print(zzz)

*****************

l'alternativa fra sendall ed un ciclo while con .send non cambia molto

Quanto inviato arriva a destinazione e cioè il software modem AX25 che visualizza quanto ricevuto e lo trasmette alla radio trasmittente

Il problema nasce sulla ricezione


Se invio qualcosa con il terminale "originale" il modem rimanda indietro l'eco di quanto inviatogli

Se invio con quello da me realizzato non restituisce nulla.

Allego 2 file catturati e visibili co WireShark o simili

Quello TERM e la cattura di un invio con il terminale nativo

Quello TestPy è quello che arriva dai miei esperimenti

Chiaramente dopo aver inviato la stringa, anche se correttamente formattata, manca qualcosa di conclusivo oppure il mio programma non è correttamente impostato per ricevere

Se qualche buon'anima riesce a vederci qualcosa...

Grazie per la pazienza






--- Ultima modifica di Pietro Bruno Lancerotto in data 2024-02-16 14:15:02 ---
--
Bruno L.
Ciao Bruno :)
Spero mi perdonerai se tento di rispondere senza, ancora, aver ben capito il Tuo problema ... non sono certo di poterTi aiutare ma mi intriga la Tua problematica

Ho fatto un "tcpdump -r" delle "sniffate" e salvato l'output in file di testo denominati come quelli da Te allegati ... molto confuso l'output dei Tuoi esperimenti, ripulendo vedo:
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
>>> trak_1 = 'CAP_SoundModem_TERM.txt'
>>> trak_2 = 'CAP_SoundModem_TestPy.txt'
>>> with open(trak_1) as f:
...     text = [x for x in f.read().splitlines() if 'localhost.8000' in x]
... 
...     
>>> for r in text:
...     print(r)
... 
...     
14:14:13.601567 IP localhost.8000 > localhost.52126: Flags [.], ack 2088010119, win 10232, length 0
14:14:13.601567 IP localhost.52126 > localhost.8000: Flags [P.], seq 4294967182:1, ack 0, win 10233, length 115
14:14:13.764903 IP localhost.52126 > localhost.8000: Flags [.], ack 170, win 10232, length 0
14:14:13.764903 IP localhost.8000 > localhost.52126: Flags [P.], seq 0:170, ack 1, win 10232, length 170

che nell'output del terminale NON sono presenti i flag di avvio ([S]) e fine ([F}) della connessione ma solo i flag di riconoscimento ([.] + ack seguente) e di invio pacchetti dati ([P]) ... posso supporre che il terminale "proprio" del Tuo trasmettiore sia collegato permanentemente?

Comunque, l'output relativo ai Tuoi tentativi è ben diverso

>>> with open(trak_2) as f:
...     text = [x for x in f.read().splitlines() if 'localhost.8000' in x]
... 
...     
>>> for r in text:
...     print(r)
... 
...     
14:46:25.883793 IP localhost.8000 > localhost.52272: Flags [S.], seq 1317438180, ack 1111647481, win 65535, options [mss 65495,nop,wscale 8,nop,nop,sackOK], length 0
14:46:25.883793 IP localhost.52272 > localhost.8000: Flags [S], seq 1111647480, win 65535, options [mss 65495,nop,wscale 8,nop,nop,sackOK], length 0
14:46:25.883793 IP localhost.52272 > localhost.8000: Flags [.], ack 1, win 10233, length 0
14:46:25.884779 IP localhost.8000 > localhost.52272: Flags [.], ack 116, win 10233, length 0
14:46:25.884779 IP localhost.52272 > localhost.8000: Flags [P.], seq 1:116, ack 1, win 10233, length 115
14:46:25.884779 IP localhost.8000 > localhost.52272: Flags [.], ack 117, win 10233, length 0
14:46:25.884779 IP localhost.52272 > localhost.8000: Flags [F.], seq 116, ack 1, win 10233, length 0
14:46:25.884779 IP localhost.52272 > localhost.8000: Flags [.], ack 2, win 10233, length 0
14:46:25.884779 IP localhost.8000 > localhost.52272: Flags [F.], seq 1, ack 117, win 10233, length 0
ove si vede stabilire la connessione (stranamente 14 centomillesimi di secondo dopo le altre operazioni) ed il Tuo programma inviare un pacchetto dati ed immediatamente un segnale di chiusura della connessione.

Vedo, dal Tuo codice che alcune cose non le hai presenti, in primo luogo che i dati trasmessi sono bytes, non stringhe, ... non ho capito dove (o perché) la connessione venga chiusa ma dalla progressione dei dati mi sembra proprio che venga chiusa dal lato del Tuo programma, il codice è, forse, parziale?

Comunque, dato che il protocollo è un IPv4, oso proporTi un tentativo, modifica il Tuo codice in questo modo:
serverName = "127.0.0.1"
serverPort = 8000
# create TCP socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as terminale:
    # connect socket to remote server at (serverName, serverPort)
    terminale.connect((serverName, serverPort))
    terminale.sendall(request)
    data = ""
    fragment = True
    while fragment:
        fragment = terminale.recv(204 8)
        data += fragment.decode('utf-8')
print("FINE TRASMISSIONE")
print( f"ricevuto: {data}")
#zzz = len(data)
#print(zzz)
e vedi che succede ...
Se vorrai far sapere, sono curioso ;)
EDIT: corretti artefatti inseriti dall'editor dei posts


--- Ultima modifica di nuzzopippo in data 2024-02-16 18:12:37 ---
Fatti non foste a viver come bruti...
posso supporre che il terminale "proprio" del Tuo trasmettiore sia collegato permanentemente?
Supponi bene , è sempre aperto anche perchè deve ricevere sempre

Prima di fare prove chiedo due delucidazioni

La "composizione" del pacchetto di byte avviene dentro a

def Invio_SM(X): # X contiene il testo da inviare

e dentro a quel def c'è anche il sendall

Visto che il socket deve rimanere aperto dove posiziono l'apertura del socket

Dentro nel def NO perchè continuerei a riaprirlo

Dentro nel Main ??

Poi ovviamente la parte di ricezione dovrebbe essere nel main in quanto sempre attiva

Allego il pastrocchio ?? :)











--- Ultima modifica di Pietro Bruno Lancerotto in data 2024-02-17 09:40:24 ---
--
Bruno L.
Pietro Bruno Lancerotto said @ 2024-02-17 09:39:42:
...

La "composizione" del pacchetto di byte avviene dentro a def Invio_SM(X): # X contiene il testo da inviare e dentro a quel def c'è anche il sendall

Visto che il socket deve rimanere aperto dove posiziono l'apertura del socket ...
Allego il pastrocchio ?? :)

AH! ... abbiamo un indizio sulla chiusura che non capivo ... mi sa che qui Ti scontri contemporaneamente con problemi di "scope", con il thread bloccante di tkinter, e con la gestione degli eventi di tkinter, storia intricata imho




... Si, credo ci sia bisogno di vedere il codice in tutta la sua consistenza, comunque Tieni presente che una variabile definita da una funzione "NON esiste" al di fuori della funzione stessa.




Ciao

Fatti non foste a viver come bruti...
... Si, credo ci sia bisogno di vedere il codice in tutta la sua consistenza,

Dicono che c'è già stato uno che si è stracciato le vesti ( nel tempio )

Non fare altrettanto :) :)

Poi ci vorrebbe il SoundModem per verificare ed è un programma Windows

Come gia detto può essere anche su un altro PC; solo questione di IP giusto


Intanto allego il pastrocchio




Ciao e grazie

--
Bruno L.
Allegati
Pietro Bruno Lancerotto said @ 2024-02-17 10:39:57:
Dicono che c'è già stato uno che si è stracciato le vesti ( nel tempio )

Non fare altrettanto :) :)
Già, vedo che hai presente la dichiarazione di variabili globali a livello di modulo, codice pulito e vedo che hai già integrato nella funzione "Invio_SM(X)" il mio precedente suggerimento ... bada bene che quel pezzo di codice è bloccante.
Pietro Bruno Lancerotto said @ 2024-02-17 10:39:57:
Poi ci vorrebbe il SoundModem per verificare ed è un programma Windows



Codice da capire nell'insieme, magari con un tentativo di collegamento ad un eco-server, proverò a farlo ma ci vorrà qualche tempo.




Intanto, tieni presente che il ciclo while di ricezione Ti bloccherà l'interfaccia, può risolversi tramite programmazione asincrona, thread e/o sub-processi.




Ciao :)

Fatti non foste a viver come bruti...
Codice da capire nell'insieme, magari con un tentativo di collegamento ad un eco-server, proverò a farlo ma ci vorrà qualche tempo.

Eco-server in funzione :)




Il router fa il port forwarding sull'indirizzo interno ..1.222:8000

Dovrebbe funzionare perchè è il sistema che uso andando in collina per verificare da remoto

Fosse che riesci a ricevere l'eco :angel: :angel: :angel: :angel: lo collego alla radio con l'APRS dei radioamatori attivo così vede così gira in aria




Da precisare:

Nella finestra superiore io ci scrivo quello che sto inviando giusto per verifica

In realtà in quella finestra deve andarci l'ECO e quanto ricevuto

Se poi tale finestra tenesse tutto quello che arriva ( un buffer di 500 righe ) magari con barra laterale per scorrere indietro





Grazie ancora



--- Ultima modifica di Pietro Bruno Lancerotto in data 2024-02-17 17:20:01 ---
--
Bruno L.
Allegati
Allora ...

Ho testato i Tuoi script su di un server così fatto:
# _*_ coding: utf-8 _*_

# utilizzare python 3

import socket               # importa il modulo socket

porta = 7679               # definisce la porta di ascolto
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)            # crea il socket
#host = socket.gethostname()      # rileva la macchina locale
host = 'localhost'
s.bind((host, porta))         # inizializza la porta
s.listen(5)                  # si pone in ascolto

print('Server in ascolto...')

try:
	while True:
		conn, ind = s.accept()      # stabilisce la connessione
		print('Stabilita connessione con', ind)
		data = conn.recv(1024)      # riceve il saluto dal client
		try:
		    print('Ricevuto : ', data.decode('utf-8'))
		except UnicodeDecodeError as e:
		    print(f'Errore ricezione: {e}')

		filename = 'mytext2.txt'
		f = open(filename, 'rb')
		l = f.read(1024)
		while (l):
			conn.sendall(l)
			print('Trasmesso : ', repr(l))
			l = f.read(1024)
		  
		f.close()

		conn.sendall(''.encode('utf8'))
		print('Fine trasmissione')
		conn.sendall('Grazie per la vostra visita'.encode('utf-8'))
		conn.close()
except KeyboardInterrupt:
	s.close()
	print("Server chiuso dall'utente : Uscita")
Messo in ascolto sulla porta 7679, questo server rimane in ascolto sin quando non lo "tronchi" con un CTL+C, va in tilt con il Tuo "0xf0", aggirato tramite la gestione degli errori e trasmette il contenuto di un file di testo contenuto nella sua stessa directory e che è composto da tre righe di numeri da 1 a 10. chiude la connessione immediatamente dopo ave trasmesso il contenuto del file, ciò per aggirare il blocco della applicazione che si avrebbe per il ciclo di ascolto.

Questa è la sessione lato server:
NzP:~$ python3 svr_03.py
Server in ascolto...
Stabilita connessione con ('127.0.0.1', 59120)
Errore ricezione: 'utf-8' codec can't decode byte 0xf0 in position 6: invalid continuation byte
Trasmesso :  b'1 2 3 4 5 6 7 8 9 10\n1 2 3 4 5 6 7 8 9 10\n1 2 3 4 5 6 7 8 9 10\n\n'
Fine trasmissione
^CServer chiuso dall'utente : Uscita
NzP:~$ 

Perché il Tuo programma possa funzionare devi :

1° definire la variabile globale terminale a livello di modulo, una cosa così:
import binascii

terminale = None
#import time

2° dare l'istruzione
    global terminale
all'inizio in tutte le funzioni che utilizzano terminale.

Con tale accorgimenti il Tuo programma funzionava, questo il suo output in una sessione IDLE
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.

== RESTART: /home/nuzzopippo/src/posts/lancerotto/socket/pkt_gui_rcs_support.py =
FINE TRASMISSIONE
Ricevuto: 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Grazie per la vostra visita

Avrai il problema del ciclo while di ricezione bloccante ... personalmente tendo a risolverlo con i thread ed un protocollo di notifiche, se vuoi Te ne faccio un esempio minimale, a modo mio, certo, io uso le classi.

Ciao

EDIT: Mi accorgo solo ora del Tuo post immediatamente precedente a questo, lo hai inserito mentre redigevo il mio è non me ne sono accorto, se i dati nella immagine sono fissi togli l'allegato, non penso sia il caso di renderli pubblici ... capisco cosa intendi, come detto mi intriga la Tua problematica ed una prova senza molte pretese si potrebbe anche tentare.

RIEDIT : provato ora (16:15) un collegamento al Tuo echo-server, il processo è rimasto congelato prima ancora di disegnare l'interfaccia, nessun messaggio di errore ricevuto, prova Tu in locale e fai sapere che succede, Ti si dovrebbe bloccare la gui quando mandi un messaggio ma da qui non è possibile sapere.

--- Ultima modifica di nuzzopippo in data 2024-02-17 15:33:27 ---

--- Ultima modifica di nuzzopippo in data 2024-02-17 16:21:10 ---
Fatti non foste a viver come bruti...
RIEDIT : provato ora (16:15) un collegamento al Tuo echo-server, il processo è rimasto congelato prima ancora di disegnare l'interfaccia, nessun messaggio di errore ricevuto, prova Tu in locale e fai sapere che succede, Ti si dovrebbe bloccare la gui quando mandi un messaggio ma da qui non è possibile sapere.
Ho provato adesso (17,14) da un pC all'altro

Il server è sul locale 222 per cui la porta da usare è la 8222

Dovresti perlomento far partire qualcosa


In ogni caso quando io invio rimane attivo il pulsante e devo chiudere forzatamente



Ho riprovato attraverso l'HotSpot del telefono ed Server/SoundModem è attivo ( 17,46 )

Fatta prova anche col "mio" terminale ed il messaggio arriva

Poi si inchioda col pulsante INVIO attivo





--- Ultima modifica di Pietro Bruno Lancerotto in data 2024-02-17 17:53:41 ---
--
Bruno L.
Pietro Bruno Lancerotto said @ 2024-02-17 17:17:19:
In ogni caso quando io invio rimane attivo il pulsante e devo chiudere forzatamente
...
Poi si inchioda col pulsante INVIO attivo
Ti avevo avvertito che sarebbe accaduto, fa parte delle tre problematiche che Ti avevo anticipato. Qui entrano in gioco DUE processi bloccanti, uno è il mainloop di tkinter, che non permette a processi esterni di agire, l'altro è il ciclo while di ascolto dei messaggi tra socket, che blocca qualsiasi altra operazione si quando non esce.

La soluzione che mi viene in mente è di spostare il ciclo di ascolto in un processo parallelo al mainloop, poi bisognerà far comunicare i due processi perché agiscano in sintonia.




Proverò a manipolare il Tuo codice per cercare di esemplificarTi un esempio minimale ma ci vorrà un po' di tempo, intanto dammi contezza di una circostanza :

Se ho valutato bene, un messaggio del Tuo programma è avvolto tra un header di 36 bytes iniziale ed un bytes finale per la terminazione, giusto?

Lo chiedo perché devo implementarmi un echo-server che non vada in tilt per quel benedetto hex di 240 ... non ho disponibili sistemi windows per il soundmodem e comunque perderei tempo a capire come diavolo funzionano le cose.




Ci leggiamo, ciao

Fatti non foste a viver come bruti...


Pagina: 1 2 3 4 5 Avanti



Esegui il login per scrivere una risposta.