hoy vamos a hablar de los 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 argumentos if (argc != 3) { // error args printf("%s: numero argumentos equivocado\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) { // error socket() printf("%s: no puedo crear el socket (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // prepara la estructura sockaddr_in para el 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 comunicación con el server remoto for (;;) { // compone mensaje para el server remoto char my_msg[MYBUFSIZE]; printf("Escribe un mensaje para el Server remoto: "); scanf("%s", my_msg); // send mensaje al server remoto if (sendto(my_socket, my_msg, strlen(my_msg), 0, (struct sockaddr *)&server, sizeof(server)) < 0) { // error send() printf("%s: error send (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // recibe una respuesta del server remoto memset(my_msg, 0, MYBUFSIZE); if (recvfrom(my_socket, my_msg, MYBUFSIZE, 0, NULL, NULL) < 0) { // errore recv() printf("%s: error recv (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // enseña la respuesta printf("%s: respuesta Server: %s\n", argv[0], my_msg); } // sale con Ok return EXIT_SUCCESS; }Ok, como se nota es ampliamente comentado y así se auto-explica, por lo cual no voy a detenerme sobre las instrucciónes y/o grupos de instrucciones (¡leer los comentarios! ¡Están ahí para eso!), pero voy a añadir, solamente, algunos detalles estructurales.
La estructura es la clásica y básica de un UDP Client:
- socket() - crea un socket
- prepara la estructura sockaddr_in para el server remoto
- sendto() + recvfrom() - loop de comunicación col server remoto
En cuanto al flujo y el estilo del main() son válidas las notas que figuran en el post sobre el Server. Para probarlo, basta con abrir dos terminales (UNIX o Linux, por supuesto), y iniciar el Server en uno y el Client en el otro; si usamos un solo ordenador el Client debe, como es lógico, conectarse con el Server en localhost. Para el argumento port se puede utilizar cualquier número elegido entre los no reservados (¡y hay que utilizar el mismo puerto para Client y Server!) El resultado es el siguiente:
terminal 1 (Server):
aldo@ao-linux-nb:~/blogtest$ ./udpserver 8888 ./udpserver: recibido mensaje del sock 3: pippo ./udpserver: recibido mensaje del sock 3: plutoterminal 2 (Client):
aldo@ao-linux-nb:~/blogtest$ ./udpclient 127.0.0.1 8888 Escribe un mensaje para el Server remoto: pippo ./udpclient: respuesta Server: me has escrito: pippo Escribe un mensaje para el Server remoto: pluto ./udpclient: respuesta Server: me has escrito: pluto Escribe un mensaje para el Server remoto: ^CComo se nota el Client y el Server se hablan y cuando el Client se desconecta (con un brutal Ctrl-C) el Server no se da cuenta (es una comunicación connectionless). ¡Mission cumplida!
¡Hasta el próximo post!