(https://i.postimg.cc/prTnQ6th/Server.png) (https://postimg.cc/R6kF4Gh4)
Buenas chicos.
Os traigo un cliente y servidor udp sencillos. El funcionamiento es simple. El cliente realiza una conexion
con el servidor enviandole datos recogidos por consola y el servidor los imprime por pantalla.
Si habeis seguido los hilos anteriores podreis notar la clasica diferencia de la conexion en ambos
protocolos. TCP es orientado a conexion pero UDP no. En estos codigos podeis ver exhibidos, a mi juicio, de manera sencilla lo anterior expuesto.
Proximamente os traere más.
¡Un saludo!
codigo del cliente:
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <sys/select.h>
#define IP_SERVER ("127.0.0.1")
#define PORT_SERVER ("9999")
int main(int argc, char **argv ){
struct addrinfo base;
memset(&base, 0, sizeof base);
base.ai_socktype = SOCK_DGRAM;
struct addrinfo *res;
if(getaddrinfo(IP_SERVER, PORT_SERVER, &base, &res) < 0){
std::cerr << "An error has ocurred in getaddrinfo" << std::endl;
std::cerr << "exiting..." << std::endl;
return -1;
}
int sock = socket(
res -> ai_family,
res -> ai_socktype,
res -> ai_protocol
);
if(sock < 0){
std::cerr << "An error has ocurred while creating socket" <<std::endl;
return -1;
}
//ya podemos enviar y recibir con nuestro socket
//a diferencia de tcp ya no es necesario establecer una conexion con el servidor
bool terminado = false;
while(!terminado){ //atencion, bucle infinito, parar con CTRL+C
//manejamos entrada por stdin
fd_set out;
FD_ZERO(&out);
FD_SET(1, &out);
int max_fd = 1;
int res_sel = select(max_fd + 1, &out, 0, 0, 0);
if(res_sel < 0){
std::cerr << "An error has ocurred while doing select" << std::endl;
return -1;
}else{
//aqui ya podemos recoger entrada por terminal
char buff[1024];
if(!fgets(buff, 1024, stdin)) break;
int bytes_sent = sendto(
sock,
buff,
1024,
0,
res -> ai_addr,
res -> ai_addrlen
);
if(bytes_sent < 0){
std::cerr << "An error has ocurred while sending bytes" << std::endl;
break;
}
std::cout << "Bytes sent: "<< bytes_sent << std::endl;
}
}
close(sock);
return 0;
}
Codigo del servidor:
#include <netdb.h>
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <cstring>
#include <cstdlib>
#define SERVER_IP NULL
/*
le digo que es null porque quiero que mi
sistema operativo me asigne la direccion de loopback
*/
#define PORT_SERVER ("9999")
int main(int argc, char **argv){
struct addrinfo base;
memset(&base, 0, sizeof base);
base.ai_family = AF_INET;
base.ai_socktype = SOCK_DGRAM;
base.ai_flags = AI_PASSIVE;
struct addrinfo *res;
if(getaddrinfo(SERVER_IP, PORT_SERVER, &base, &res) < 0){
std::cerr << "An error has ocurred with the getaddrinfo" << std::endl;
std::cerr << "exiting..." << std::endl;
return -1;
}
int sock = socket(
res -> ai_family,
res -> ai_socktype,
res -> ai_protocol
);
if(sock < 0){
std::cerr << "An error has ocurred while creating socket" << std::endl;
return -1;
}
if(bind(sock, res -> ai_addr, res -> ai_addrlen) < 0){
std::cerr << "An error has ocurred while binding ip to socket" << std::endl;
return -1;
}
//ya podemos utilizar nuestro socket para recibir mensajes
bool terminado = false;
while(!terminado){ //atencion, bucle infinito, parar con CTRL+C
struct sockaddr_storage client; //esta estructura sirve simplemente para almacenar informacion del cliente
socklen_t client_size = sizeof client;
char buff[1024]; //aqui recibimos los mensajes
int bytes_received = recvfrom(
sock,
buff,
1024,
0,
(struct sockaddr *)&client,
&client_size
);
if(bytes_received == 0){
std::cout << "Connection closed by peer" << std::endl;
break;
}
if(bytes_received < 0){
std::cerr << "An error has ocurred in recvfrom" << std::endl;
return -1;
}
char client_buffer[128];
char port_buffer[128];
getnameinfo(
(struct sockaddr *)&client,
client_size,
client_buffer,
128,
port_buffer,
128,
NI_NUMERICHOST | NI_NUMERICSERV
);
std::cout << "ip:" << client_buffer << std::endl;
std::cout << "port:" << port_buffer << std::endl;
printf("%.*s", bytes_received, buff);
}
close(sock);
return 0;
}
Muy buenooo!!
Muchas gracias por compartirlo!
Saludos,
ANTRAX