oggi parleremo degli UDP client... |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <errno.h> #define MYBUFSIZE 1024 int main(int argc, char *argv[]) { // test argomenti if (argc != 3) { // errore args printf("%s: numero argomenti errato\n", argv[0]); printf("uso: %s host port [i.e.: %s 127.0.0.1 8888]\n", argv[0], argv[0]); return EXIT_FAILURE; } // crea un socket int my_socket; if ((my_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { // errore socket() printf("%s: non posso creare il socket (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // prepara la struttura sockaddr_in per il server remoto struct sockaddr_in server; // (remote) server socket info memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; // set address family server.sin_addr.s_addr = inet_addr(argv[1]); // set server address server.sin_port = htons(atoi(argv[2])); // set server port number // loop di comunicazione col server remoto for (;;) { // compone messaggio per il server remoto char my_msg[MYBUFSIZE]; printf("Scrivi un messaggio per il Server remoto: "); scanf("%s", my_msg); // send messaggio al server remoto if (sendto(my_socket, my_msg, strlen(my_msg), 0, (struct sockaddr *)&server, sizeof(server)) < 0) { // errore send() printf("%s: errore send (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // riceve una risposta dal server remoto memset(my_msg, 0, MYBUFSIZE); if (recvfrom(my_socket, my_msg, MYBUFSIZE, 0, NULL, NULL) < 0) { // errore recv() printf("%s: errore recv (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // mostra la risposta printf("%s: risposta Server: %s\n", argv[0], my_msg); } // esco con Ok return EXIT_SUCCESS; }Ok, come vedete è ampiamente commentato e quindi è auto-esplicativo, per cui non mi dilungherò sulle singole istruzioni e/o gruppi di istruzioni (leggete i commenti! sono li per quello!), ma aggiungerò, solo, qualche dettaglio strutturale.
La struttura è quella classica e basica di un UDP Client:
- socket() - crea un socket
- prepara la struttura sockaddr_in per il server remoto
- sendto() + recvfrom() - loop di comunicazione col server remoto
Per quanto riguarda il flusso e lo stile del main() valgono le note elencate nel post sul Server. Per testarlo è sufficiente aprire due terminali (UNIX o Linux, ovviamente), e avviare in uno il Server e nell'altro il Client; se proviamo in una macchina sola il Client deve, come è logico, collegarsi al Server su localhost. Per l'argomento port si può usare un numero qualsiasi scelto tra quelli non riservati (e bisogna usare lo stesso port per Client e Server!) Il risultato sarà il seguente:
terminale 1 (Server):
aldo@ao-linux-nb:~/blogtest$ ./udpserver 8888 ./udpserver: ricevuto messaggio dal sock 3: pippo ./udpserver: ricevuto messaggio dal sock 3: plutoterminale 2 (Client):
aldo@ao-linux-nb:~/blogtest$ ./udpclient 127.0.0.1 8888 Scrivi un messaggio per il Server remoto: pippo ./udpclient: risposta Server: mi hai scritto: pippo Scrivi un messaggio per il Server remoto: pluto ./udpclient: risposta Server: mi hai scritto: pluto Scrivi un messaggio per il Server remoto: ^CCome si nota il Client e il Server si parlano e quando il Client si scollega (con un brutale Ctrl-C) il Server non se ne accorge (è una comunicazione connectionless). Missione compiuta!
Ciao e al prossimo post!
Nessun commento:
Posta un commento