• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Problema risolto [C#] Primi passi con i Socket

gedamial

Utente Senior
Autore del topic
9 Giugno 2010
1.937
69
Miglior risposta
0
Salve.

Dopo molto tempo eccomi di nuovo qui a parlare dei Socket. Ebbene, questo è un argomento che mi interessa moltissimo ma che nessuno in rete spiega in modo chiaro e capiente.
Allora, ho iniziato a smanettare con questi Socket già da molto tempo... ma senza successo.

Ragion per cui ora mi ritrovo ad affrontare nuovamente questo argomento, cominciando con la programmazione Console Application in C#

Bene, ecco quel che son riuscito a fare fino ad ora:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Ho creato un Socket s (protocollo TCP). Nella entry-point ho "bindato" il socket sul mio indirizzo IP e sulla porta 100. Poi, ho settato il Listen a 5 client. Creo un ulteriore socket che "rappresenta" il client accettato dal server e lo chiamo handler(delucidatemi su questa cosa, forse sto sbagliando, chiedo più dettagli riguardo quella riga di codice)
Creo un messaggio predefinito di benvenuto per il client che si connette ("Hello World!") salvandolo nella variabile di tipo matrice di byte mess (domanda: perché deve essere un byte? non posso spedire messaggi che siano stringhe, interi, caratteri...?)
Chiudo la comunicazione del socket handler in modo che non possa più ricevere o inviare messaggi al server. Infine, chiudo effettivamente la comunicazione (domanda: qual è la differenza tra handler.Shutdown e handler.Close?)

Poi, come faccio a reperire l'indirizzo IP del client che si è connesso al server per poi ad esempio salvarlo in un file .txt?

Per ora, potreste limitarvi a rispondere a queste domande? Don't worry, presto ce ne saranno altre in arrivo :emoji_relieved:

Grazie in anticipo!

Taggo qualcuno che potrebbe intendersene: @System32 - @nothing - @Dvdxseo - @TBH

P.S: Il prefisso è "Problema" perché tra un po' spunteranno i problemi veri e propri D:
 
Ultima modifica:
Ma funziona il programma? Cioè l'hai provato e non funziona, o funziona e vuoi capire perché?

2) Devono essere byte, perché tu mandi byte. Se hai una stringa, la converti in byte e la invii.
3) Shutdown e Close:
Perfavore, Entra oppure Registrati per vedere i Link!
 
Accept restituisce un socket per gesrire l'utente connesso. Per ottenere l'ip devi usare la proprieta EndPoint ed eseguire il casting in IpEndPoint. Devi lavorare con i byte dato che la comunicazione tcp/ip si basa sul trafsferimento di bit.


Shoutdown si limita a disabilitare le operazioni di trasferimento , invece close rilascia le risorse usate e termina la connessione

Inviato dal mio GT-S6500 con Tapatalk 2
 
Ultima modifica:
  • Like
Reactions: 1 person
Accept restituisce un socket per gesrire l'utente connesso. Per ottenere l'ip devi usare la proprieta EndPoint ed eseguire il casting in IpEndPoint. Devi lavorare con i byte dato che la comunicazione tcp/ip si basa sul trafsferimento di bit.


Shoutdown si limita a disabilitare le operazioni di trasferimento , invece close rilascia le risorse usate e termina la connessione

Inviato dal mio GT-S6500 con Tapatalk 2
Sapendo che il client connesso é HANDLER, come dovrei impostare il codice per ricavare l'ip di tale socket?

P.S: il parametro del metodo Listen() indica il massimo numero di client che possono rimanere in coda ad aspettare che il server finisca una comunicazione con uno per poi passare al prossimo?
 
Sapendo che il client connesso é HANDLER, come dovrei impostare il codice per ricavare l'ip di tale socket?

P.S: il parametro del metodo Listen() indica il massimo numero di client che possono rimanere in coda ad aspettare che il server finisca una comunicazione con uno per poi passare al prossimo?

Listen , mette in ascolto il socket e accetta un parametro int , che indica la massima lunghezza della coda d'attesa.
Accept() estrae in modo sincrono dalla coda , la prima richiesta di connessione in attesa.Ovviamente estraendo si crea un nuovo spazio. La coda ovviamente è di tipo FIFO ^^

per ottenere l'ip come scritto sopra devi fare così
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
 
Ultima modifica:
Listen , mette in ascolto il socket e accetta un parametro int , che indica la massima lunghezza della coda d'attesa.
Accept() estrae in modo sincrono dalla coda , la prima richiesta di connessione in attesa.Ovviamente estraendo si crea un nuovo spazio. La coda ovviamente è di tipo FIFO ^^

per ottenere l'ip come scritto sopra devi fare così
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

--- 1 ---
Da un punto di vista logico, se il metodo Parse() serve a convertire una stringa in un'istanza IPAddress ... ma allo stesso tempo sto fornendo la stringa dell'IP remoto connesso ... non faccio prima a stampare quest'ultima facendo:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

--- 2 ---
Il mio server fa solo una cosa: si connette con il client e gli invia un messaggio.
Io vorrei che il mio server, una volta essersi connesso con il client, ASPETTI un messaggio da quest'ultimo che lui interpreterà come "richiesta"

Esempio di dove voglio arrivare alla fine di questo luuungo thread:

Server
Accetta client
Aspetta una richiesta
se richiesta == time
allora invia che ore sono
se richiesta == data
allora invia che data è
se richiesta == crediti
allora invia il mio nome (e... anche quello di coloro che mi hanno aiutato :emoji_relieved:)
se richiesta == ecc... ecc... ecc...
allora ecc... ecc... ecc...

Client
Si connette al server
Manda richiesta
Riceve risposta

Io direi di iniziare dal Server. Allora, una volta fatto questo:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

quando provo a connettermi via comando telnet 2.232.196.230 100 mi viene causata un eccezione che non riesco a risolvere (screen:
Perfavore, Entra oppure Registrati per vedere i Link!
)

Come risolvere?
 
@HabboFanNumero1

Si parse in quel caso può rilevarsi non utile , serve solo per certificare che effettivamente sia un ip valido.
Comunque torniamo al codice ti metto in evidenza alcune parti errate

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

secondo te s può mai essere connesso abbiamo detto che gestiamo i socket prendendoli da quella famosa lista d'attesa.
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

poi immaginiamo di non ricevere dati in frazioni di ms la tua applicazione come scritta va in eccezione ecco perché esiste un utile proprietà : Available

un altra cosa che ho notato perché usi due array di byte ?
per la ricezione basta una cosa del genere :
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

il problema che hai supposto è se sono >1024 come faccio ? semplice li leggi nella lettura successiva ... questo ti fa capire che devi usare un while , magari in un thread separato ma questo è solo un esempio,quindi per ora lasciamo stare la suddivisione delle azioni fondamentali in thread.

Ti posto il codice del server corretto .


Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

ok ti scrivo anche il client

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
 
Ultima modifica:
@HabboFanNumero1

Si parse in quel caso può rilevarsi non utile , serve solo per certificare che effettivamente sia un ip valido.
Comunque torniamo al codice ti metto in evidenza alcune parti errate

secondo te s può mai essere connesso abbiamo detto che gestiamo i socket prendendoli da quella famosa lista d'attesa.
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

poi immaginiamo di non ricevere dati in frazioni di ms la tua applicazione come scritta va in eccezione ecco perché esiste un utile proprietà : Available

un altra cosa che ho notato perché usi due array di byte ?
per la ricezione basta una cosa del genere :

il problema che hai supposto è se sono >1024 come faccio ? semplice li leggi nella lettura successiva ... questo ti fa capire che devi usare un while , magari in un thread separato ma questo è solo un esempio,quindi per lasciamo stare la suddivisione delle azioni fondamentali in thread.

Ti posto il codice del server corretto .

ok ti scrivo anche il client

Grazie mille per il client, ovviamente l'ho studiato senza fare un bruto copia e incolla e ti dico due cose:

1. Ho modificato in modo che il client mi facesse inserire una nuova richiesta ogni volta che finisco di farne una... ma la prima volta che inserisco la richiesta non succede nulla.. le successive volte si

Client:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

2. Mi spieghi più a fondo queste righe?

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

In realtà ho capito a cosa servono dato che prima ho fatto anche io in questo modo, ma vorrei che mi spiegassi più a fondo quel += (so a cosa serve in generale, dico in questo contesto)


Grazie mille =)
 
@HabboFanNumero1 è ovvio che non devi fare un copia e incolla , io ti ho dato solo uno schema di partenza a migliorarlo e personalizzarlo devi essere tu.

il += equivale a : data=data + Encoding.ASCII.GetString(bytes, 0, bytesReceived);
il resto , è semplice leggi dei byte ricevuti ed usi GetString(byte b[],int start,int stop)
 
eh appunto tu l'hai modificato , per fare più richieste ... quindi devi eseguire un timeout basta aggiungere nel client

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Mitico! Con quella piccola pausa ora va tutto bene!

Ora vorrei fare una piccola domanda: per portare il server e il client su una Windows Form, le righe di codice son le stesse?
 
Mitico! Con quella piccola pausa ora va tutto bene!

Ora vorrei fare una piccola domanda: per portare il server e il client su una Windows Form, le righe di codice son le stesse?

si , l'unica cosa che deve tener conto ... l'attesa dei messaggi non puoi farla in while sul thread di UI (altrimenti blocchi tutto) , bensì creare un altro thread per ricevere i messaggi. Altro problema , se deve scrivere il messaggio su un componente devi usare un delegate per gestirlo.
 
si , l'unica cosa che deve tener conto ... l'attesa dei messaggi non puoi farla in while sul thread di UI (altrimenti blocchi tutto) , bensì creare un altro thread per ricevere i messaggi. Altro problema , se deve scrivere il messaggio su un componente devi usare un delegate per gestirlo.

Aspetta non ho ben capito. Ecco il codice sorgente della SERVER FORM:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Però non riesco a passare come argomento il Socket handler...e non credo di aver settato il thread in maniera corretta :/
 
Ultima modifica:
Aspetta non ho ben capito. Ecco il codice sorgente della SERVER FORM:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Però non riesco a passare come argomento il Socket handler...e non credo di aver settato il thread in maniera corretta :/

dovresti passarlo al thread quando chiami start e successivamente alla procedura ed elimina quei Console.WriteLine ^^