Il socket e i suoi metodi

I socket sono gli endpoint di un canale di comunicazione bidirezionale. Possono comunicare all'interno di un processo, tra processi sulla stessa macchina o tra processi su macchine diverse. In una nota simile, un socket di rete è un endpoint in un flusso di comunicazione tra due programmi in esecuzione su una rete di computer come Internet. È una cosa puramente virtuale e non significa alcun hardware. La presa di rete può essere identificata da una combinazione univoca di indirizzo IP e numero di porta. I socket di rete possono essere implementati su diversi tipi di canali come TCP, UDP e così via.

I diversi termini relativi alla presa utilizzata nella programmazione di rete sono i seguenti:

Dominio

Il dominio è la famiglia di protocolli utilizzata come meccanismo di trasporto. Questi valori sono costanti come AF_INET, PF_INET, PF_UNIX, PF_X25 e così via.

genere

Tipo indica il tipo di comunicazione tra due endpoint, in genere SOCK_STREAM per i protocolli orientati alla connessione e SOCK_DGRAM per i protocolli senza connessione.

Protocollo

Questo può essere usato per identificare una variante di un protocollo all'interno di un dominio e tipo. Il suo valore predefinito è 0. Questo di solito viene omesso.

Nome host

Funziona come identificatore di un'interfaccia di rete. Un nome host può essere una stringa, un indirizzo a quattro punti o un indirizzo IPV6 in notazione con due punti (e possibilmente con un punto).

Porta

Ogni server ascolta i client che chiamano su una o più porte. Una porta può essere un numero di porta Fixnum, una stringa contenente un numero di porta o il nome di un servizio.

Modulo Socket di Python per la programmazione Socket

Per implementare la programmazione socket in Python, dobbiamo usare il modulo Socket. Di seguito è riportata una semplice sintassi per creare un Socket:

import socket
s = socket.socket (socket_family, socket_type, protocol = 0)

Qui, dobbiamo importare la libreria socket e quindi creare un semplice socket. Di seguito sono riportati i diversi parametri utilizzati durante la creazione del socket:

  • socket_family - Questo è AF_UNIX o AF_INET, come spiegato in precedenza.

  • socket_type - Questo è SOCK_STREAM o SOCK_DGRAM.

  • protocol - Questo di solito viene omesso, il valore predefinito è 0.

Metodi socket

In questa sezione, impareremo i diversi metodi socket. I tre diversi set di metodi socket sono descritti di seguito:

  • Metodi socket server
  • Metodi socket client
  • Metodi socket generali

Metodi socket server

Nell'architettura client-server, c'è un server centralizzato che fornisce il servizio e molti client ricevono il servizio da quel server centralizzato. I client eseguono anche la richiesta al server. Alcuni importanti metodi socket del server in questa architettura sono i seguenti:

  • socket.bind() - Questo metodo associa l'indirizzo (nome host, numero di porta) al socket.

  • socket.listen()- Questo metodo fondamentalmente ascolta le connessioni effettuate al socket. Avvia il listener TCP. Il backlog è un argomento di questo metodo che specifica il numero massimo di connessioni in coda. Il suo valore minimo è 0 e il valore massimo è 5.

  • socket.accept()- Questo accetterà la connessione client TCP. La coppia (conn, address) è la coppia del valore di ritorno di questo metodo. In questo caso, conn è un nuovo oggetto socket utilizzato per inviare e ricevere dati sulla connessione e l'indirizzo è l'indirizzo associato al socket. Prima di utilizzare questo metodo, è necessario utilizzare il metodo socket.bind () e socket.listen ().

Metodi socket client

Il client nell'architettura client-server richiede il server e riceve i servizi dal server. Per questo, esiste un solo metodo dedicato ai clienti:

  • socket.connect(address)- questo metodo intima attivamente la connessione al server o in parole semplici questo metodo collega il client al server. L'argomento address rappresenta l'indirizzo del server.

Metodi socket generali

Oltre ai metodi socket client e server, ci sono alcuni metodi socket generali, che sono molto utili nella programmazione socket. I metodi socket generali sono i seguenti:

  • socket.recv(bufsize)- Come suggerisce il nome, questo metodo riceve il messaggio TCP dal socket. L'argomento bufsize sta per dimensione del buffer e definisce il numero massimo di dati che questo metodo può ricevere in qualsiasi momento.

  • socket.send(bytes)- Questo metodo viene utilizzato per inviare i dati al socket che è connesso alla macchina remota. L'argomento byte darà il numero di byte inviati al socket.

  • socket.recvfrom(data, address)- Questo metodo riceve i dati dal socket. Questo metodo restituisce un valore a due coppie (dati, indirizzo). Dati definisce i dati ricevuti e l'indirizzo specifica l'indirizzo del socket che invia i dati.

  • socket.sendto(data, address)- Come suggerisce il nome, questo metodo viene utilizzato per inviare dati dal socket. Questo metodo restituisce un valore a due coppie (dati, indirizzo). I dati definiscono il numero di byte inviati e l'indirizzo specifica l'indirizzo della macchina remota.

  • socket.close() - Questo metodo chiuderà il socket.

  • socket.gethostname() - Questo metodo restituirà il nome dell'host.

  • socket.sendall(data)- Questo metodo invia tutti i dati al socket che è connesso a una macchina remota. Trasferirà incautamente i dati fino a quando non si verifica un errore e se si verifica utilizza il metodo socket.close () per chiudere il socket.

Programma per stabilire una connessione tra server e client

Per stabilire una connessione tra server e client, dobbiamo scrivere due diversi programmi Python, uno per il server e l'altro per il client.

Programma lato server

In questo programma socket lato server, useremo il socket.bind()metodo che lo lega a uno specifico indirizzo IP e porta in modo che possa ascoltare le richieste in arrivo su quell'IP e quella porta. Successivamente, utilizziamo l'estensionesocket.listen()metodo che mette il server in modalità di ascolto. Il numero, diciamo 4, come argomento disocket.listen()significa che 4 connessioni vengono mantenute in attesa se il server è occupato e se un quinto socket tenta di connettersi, la connessione viene rifiutata. Invieremo un messaggio al cliente utilizzando il filesocket.send()metodo. Verso la fine, usiamo ilsocket.accept() e socket.close()metodo per avviare e chiudere la connessione rispettivamente. Di seguito è riportato un programma lato server:

import socket
def Main():
   host = socket.gethostname()
   port = 12345
   serversocket = socket.socket()
   serversocket.bind((host,port))
   serversocket.listen(1)
   print('socket is listening')
   
   while True:
      conn,addr = serversocket.accept()
      print("Got connection from %s" % str(addr))
      msg = 'Connecting Established'+ "\r\n"
      conn.send(msg.encode('ascii'))
      conn.close()
if __name__ == '__main__':
   Main()

Programma lato client

Nel programma socket lato client, dobbiamo creare un oggetto socket. Quindi ci collegheremo alla porta su cui è in esecuzione il nostro server - 12345 nel nostro esempio. Dopodiché stabiliremo una connessione utilizzando ilsocket.connect()metodo. Quindi utilizzando ilsocket.recv()metodo, il client riceverà il messaggio dal server. Alla fine, ilsocket.close() metodo chiuderà il client.

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

host = socket.gethostname()
port = 12345

s.connect((host, port))
msg = s.recv(1024)

s.close()
print (msg.decode('ascii'))

Ora, dopo aver eseguito il programma lato server, avremo il seguente output sul terminale:

socket is listening
Got connection from ('192.168.43.75', 49904)

E dopo aver eseguito il programma lato client, otterremo il seguente output su un altro terminale:

Connection Established

Gestione delle eccezioni relative ai socket di rete

Ci sono due blocchi vale a dire try e exceptche può essere utilizzato per gestire le eccezioni dei socket di rete. Di seguito è riportato uno script Python per la gestione delle eccezioni:

import socket
host = "192.168.43.75"
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try:
   s.bind((host,port))
   s.settimeout(3)
   data, addr = s.recvfrom(1024)
   print ("recevied from ",addr)
   print ("obtained ", data)
   s.close()
except socket.timeout :
   print ("No connection between client and server")
   s.close()

Produzione

Il programma di cui sopra genera il seguente output:

No connection between client and server

Nello script precedente, prima abbiamo creato un oggetto socket. Questo è stato seguito fornendo l'indirizzo IP dell'host e il numero di porta su cui è in esecuzione il nostro server - 12345 nel nostro esempio. Successivamente, viene utilizzato il blocco try e al suo interno utilizzando ilsocket.bind()metodo, proveremo a collegare l'indirizzo IP e la porta. Stiamo usandosocket.settimeout()metodo per impostare il tempo di attesa per il client, nel nostro esempio stiamo impostando 3 secondi. Viene utilizzato il blocco eccetto che stamperà un messaggio se non verrà stabilita la connessione tra server e client.