//metodo eseguito al click sul pulsante connetti private void btnConnect_Click(object sender, EventArgs e) { //vengono memorizzati il nome utente e //viene aggiornata la casella di testo _userName = txtUserName.Text.Trim(); _setText = SetText; //viene creato e riempito un pacchetto di richiesta di join alla chat Packet sendData = new Packet(); sendData.DataIdentifier = DataTypeIdentifier.Login; sendData.UserName = _userName; //viene creato un Socket UDP _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //viene creato un oggetto contenente l'indirizzo IP e la porta del server IPAddress serverIP = IPAddress.Parse(txtServerAddress.Text); int serverPort = int.Parse(txtServerPort.Text); _epServer = new IPEndPoint(serverIP, serverPort); //il pacchetto creato viene convertito in un'array di byte _dataStream = sendData.ToByteArray(); //il pacchetto creato viene spedito al server _clientSocket.BeginSendTo(_dataStream, 0, _dataStream.Length, SocketFlags.None, _epServer, SendData, null); //tutti gli oggetti vengono sempre passati per referenza //il client si mette ora in ascolto dei messaggi provenienti dal server EndPoint ep = _epServer; _dataStream = new byte[Properties.Settings.Default.MAX_PACKET_LENGTH]; _clientSocket.BeginReceiveFrom(_dataStream, 0, _dataStream.Length, SocketFlags.None, ref ep, ReceiveData, null); }
//metodo eseguito quando l'utente clicca sul pulsante invia private void btnSend_Click(object sender, EventArgs e) { if (txtMessage.Text == "") //si controlla se il campo del messaggio è stato riempito return; //da implementare il messaggio d'errore //viene creato e riempito un nuovo pacchetto Packet sendData = new Packet(); sendData.DataIdentifier = DataTypeIdentifier.Message; sendData.UserName = _userName; sendData.Message = txtMessage.Text; //il pacchetto viene convertito in un array di bytes byte[] data = sendData.ToByteArray(); //metodo non bloccante, preferibile alle altre chiamate che sono invece bloccanti //questo è il modo più pulito di programmare perchè non viene occupata //la CPU e non occorre preoccuparsi della gestione dei thread _clientSocket.BeginSendTo(data, 0, data.Length, SocketFlags.None, _epServer, SendData, _epServer); //la casella di testo del messaggio viene svuotata txtMessage.Clear(); }
void ReceiveData(IAsyncResult result) { //i byte ottenuti vengono deserializzati Packet receivedData = new Packet(_dataStream); //si controlla il contenuto del campo Message del pacchetto ricevuto //un puntatore a null è uguale a "" if (!string.IsNullOrEmpty(receivedData.Message)) { //per scrivere su un elemento grafico da un thread diverso da //quello che ha generato l'elemento, si usano la Invoke e le Delegate //txtConversation.Text += receivedData.Message; //infatti dà ERRORE Invoke(_setText, receivedData.Message); } EndPoint ep = _epServer; _clientSocket.BeginReceiveFrom(_dataStream, 0, _dataStream.Length, SocketFlags.None, ref ep, ReceiveData, _epServer); }
//metodo eseguito alla chiusura della finestra private void frmClientUDP_FormClosing(object sender, FormClosingEventArgs e) { //viene visualizzata una MessageBox di conferma //di solito è meglio mettere più istruzioni su una riga che annidare troppo if (MessageBox.Show(this, "Vuoi terminare la sessione?", "Domanda", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No) { e.Cancel = true; return; } //viene creato e riempito un pacchetto di tipologia Logout Packet sendData = new Packet(); sendData.DataIdentifier = DataTypeIdentifier.Logout; sendData.UserName = _userName; //il pacchetto viene convertito in un array di bytes byte[] bytes = sendData.ToByteArray(); //in questo caso si usa il socket in modo sincrono //con il metodo SendTo() per inviare il pacchetto _clientSocket.SendTo(bytes, 0, bytes.Length, SocketFlags.None, _epServer); //il Socket viene chiuso _clientSocket.Close(); }