también Bane se pregunta: ¿No es un blog de cine, eh? |
#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) { // errore args printf("%s: numero argumentos equivocado\n", argv[0]); printf("uso: %s host port [i.e.: %s 127.0.0.1 9999]\n", argv[0], argv[0]); return EXIT_FAILURE; } // crea un socket int my_socket; if ((my_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // errore socket() printf("%s: could not create 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 server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(argv[1]); server.sin_port = htons(atoi(argv[2])); // conexión al server remoto if (connect(my_socket, (struct sockaddr *)&server, sizeof(server)) < 0) { // errore connect() printf("%s: connect failed (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // loop de comunicación col server remoto for (;;) { // compone mensaje para el server remoto char my_msg[MYBUFSIZE]; printf("Escibe un mensaje para el Server remoto: "); scanf("%s", my_msg); // send mensaje al server remoto if (send(my_socket, my_msg, strlen(my_msg), 0) < 0) { // error send() printf("%s: send failed (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // recibe una respuesta del server remoto memset(my_msg, 0, MYBUFSIZE); if (recv(my_socket, my_msg, MYBUFSIZE, 0) < 0) { // errore recv() printf("%s: recv failed (%s)\n", argv[0], strerror(errno)); return EXIT_FAILURE; } // enseña la respuesta printf("%s: Server reply: %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! ¡Estan ahi para eso!), pero voy a añadir, solamente, algunos detalles estructurales.
la estructura es la clásica y básica de un Socket Client:
- socket() - crea un socket
- prepara la estructura sockaddr_in para el server remoto
- connect() - conexión al server remoto
- send() + recv() - loop di 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@linux-nb:~/blogtest$ ./socket_server 9999 ./socket_server: espera conexiones entrantes... ./socket_server: recibido mensaje del sock 4: pippo ./socket_server: recibido mensaje del sock 4: pluto ./socket_server: client disconnectedterminal 2 (Client):
aldo@linux-nb:~/blogtest$ ./socket_client 127.0.0.1 9999 Escribe un mensaje para el Server remoto: pippo ./socket_client: Server reply: me has escrito: pippo Escribe un mensaje para el Server remoto: pluto ./socket_client: Server reply: 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 se da cuenta. ¡Mission cumplida!
¡Hasta el próximo post!