domingo, 6 de mayo de 2007

Sockets TCP y UDP

A continuación pego dos ejemplos de como usar sockets TCP y UDP.


Cliente TCP:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>

/*
* Ejemplo de Sockets cliente TCP
*/
int main () 
{

/* Datos de conexion */
char *host = "localhost";
int port = 9999;

/* Cadena a enviar */
char *data = "Cadena de prueba";

/* Obtenemos el host */
struct hostent *host_name;
if ((host_name = gethostbyname(host))==0) 
{
perror ("gethostbyname()");
exit (EXIT_FAILURE);
}

/* Configura el socket */
struct sockaddr_in pin; 
bzero (&pin, sizeof(pin));
pin.sin_family =  AF_INET;
pin.sin_addr.s_addr = htonl(INADDR_ANY);
pin.sin_addr.s_addr = ((struct in_addr *)(host_name->h_addr))->s_addr;
pin.sin_port = htons (port);


/* Crea un socket TCP */
int socket_descriptor = socket (AF_INET, SOCK_STREAM, 0);
if (socket_descriptor == -1) 
{ 
perror ("socket()");
exit (EXIT_FAILURE);
}


/* Conecta con el servidor */
if (connect(socket_descriptor, (void *)&pin, sizeof(pin))==-1) 
{
perror ("connect()");
exit (EXIT_FAILURE);
}

/* Envia los datos al servidor */
if (send(socket_descriptor, data, strlen(data), 0) == -1) 
{
perror ("send()");
exit (EXIT_FAILURE);
}

/* Lee la respuesta */
static char buffer [2048];
if (recv(socket_descriptor, buffer, sizeof(buffer), 0) == -1) {

perror ("recv()");
exit (EXIT_FAILURE);
}

/* Datos recibidos */
printf ("%s\n", buffer);
}







Servidor TCP:


#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

#define BUFFER_SIZE 1024

/*
* Ejemplo Socket servidor TCP
*/
int main() 
{

/* Descriptor del socket */
int socket_descriptor;

/* Puerto al que escuchara el servidor */
int port = 9999;


/* Configuracion del socket */
struct sockaddr_in sin; 

/* Crea un socket TCP */
socket_descriptor = socket (AF_INET, SOCK_STREAM, 0);
if (socket_descriptor == -1) 
{
perror("socket()");
exit(EXIT_FAILURE);
}

/* Configura el socket */
bzero (&sin, sizeof(sin));
sin.sin_family =  AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons (port);

/* Une el socket al puerto X */
if (bind(socket_descriptor,(struct sockaddr *)&sin,sizeof(sin)) == -1) 
{ 
perror("bind()");  
exit(EXIT_FAILURE);
}

/* Configura la cola del socket */
if (listen(socket_descriptor, 20) == -1) 
{
perror("listen()");  
exit(EXIT_FAILURE);
}


/* Para obtener la configuracion del socket */
struct sockaddr_in pin;
int address_size;

/* Descriptor del socket temporal */
int temp_socket_descriptor;

/* Buffer de recepcion  */
char buffer[BUFFER_SIZE];

/* Bucle principal de recepcion y envio de paquetes */
while (1) 
{
/* Limpieza del buffer */
memset (buffer, '\0', BUFFER_SIZE);

/* Aceptamos la conexion */
temp_socket_descriptor = 
accept(socket_descriptor,(struct sockaddr*)&pin,&address_size);

if (temp_socket_descriptor == -1) 
{ 
perror("accept()");  
exit(EXIT_FAILURE);
}

/* Recibimos datos */
if (recv(temp_socket_descriptor,buffer,sizeof(buffer),0)==-1) 
{ 
perror("recv()");  
exit(EXIT_FAILURE);
}

printf ("Recibido: %s\n",buffer); 

/* Enviamos datos */
if (send(temp_socket_descriptor, "Recibido\n", 9,0) == -1) 
{ 
perror("send()");  
exit(EXIT_FAILURE);
}

/* Cierre del descriptor de archivo */
close(temp_socket_descriptor);
}
}




Paquetes UDP:

#include <stdio.h>

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <netinet/ip.h>
#include <netinet/udp.h>


int main(void) 
{
/* socket */
int sock;

/* Tamaño del paquete UDP */
unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct udphdr);

/* Buffer de tamaño suficiente para un paquete UDP */
unsigned char buffer[buffer_size];
memset (buffer, 0, buffer_size);

/* Cabecera IP */
struct iphdr *ip = (struct iphdr *)buffer;

/* Cabecera UDP */
struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));

/* Crea el socket */
if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1) 
{ 
perror("socket()"); 
exit(EXIT_FAILURE); 
}

/* Establece las opciones del socket */
int o = 1;
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&o,sizeof(o)) == -1) 
{ 
perror("setsockopt()"); 
exit(EXIT_FAILURE); 
}

/* Rellena la cabecera IP */
ip->version = 4;
ip->ihl = 5;
ip->id = htonl(random());
ip->saddr = inet_addr("1.2.3.4");
ip->daddr = inet_addr("1.2.3.4");
ip->ttl = 255;
ip->protocol = IPPROTO_UDP;
ip->tot_len = buffer_size;
ip->check = 0;

/* Rellena la cabecera UDP */
udp->source = htons(1234);
udp->dest = htons(1234);
udp->len = buffer_size;
udp->check = 0; /* falta calcular checksum  */


struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = udp->source;
addr.sin_addr.s_addr = ip->saddr;

/* Envio del paquete */
if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&addr,
sizeof(struct sockaddr_in))) == -1) 
{
perror("send()");
exit(1);
}

return 0;
}