Tp 4 (Socket App.) - Redes de Computadoras

Anuncio
Facultad de Ingeniería
66.48 – Seminario de Redes de Computadoras
Trabajo Práctico Nº: 4
Tema: Sockets TCP/UDP
66.48 – Seminario de Redes de Computadoras
(2º cuatrimestre 2007)
Docentes: Ing. Marcelo Utard; Ing. Pablo Ronco
Alumnos: Bianchi Mariano
Soto Fernando
Ricci Alberto
79854
74824
78757
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Introducción: ¿Qué es un Socket?
Los sockets son una abstracción que provee un sistema operativo para realizar comunicaciones
entre procesos en forma transparente. Como definición informal podrían definirse como una manera de
que dos programas (procesos) se comuniquen entre si usando descriptores de archivos Unix estándar.
Lo que esto quiere decir es que cuando un programa Unix realiza cualquier tipo de E/S, lo hacen
leyendo o escribiendo a un descriptor de archivo. Un descriptor de archivo es simplemente un número
entero asociado a un archivo abierto. Pero ese archivo puede ser una conexión de red, un FIFO, un
terminal, un archivo real en el disco, u otra cosa. Así que cuando se desea comunicar dos procesos
por medio de una red puede hacerse a través de un descriptor de archivo.
Resumiendo:
•
•
Un socket es una interfaz de entrada-salida de datos que permite la intercomunicación entre
procesos.
Los procesos pueden estar ejecutándose en el mismo o en distintos sistemas, unidos mediante
una red.
Dominios de comunicación
Los sockets se crean dentro de un dominio de comunicación, igual que un archivo se crea dentro de
un filesystem.
El dominio de comunicación nos dice donde se encuentran los procesos que se van a
intercomunicar. Si los procesos están en el mismo sistema, el dominio de comunicación será
AF_UNIX, si los procesos están en distintos sistemas y estos se hallan unidos mediante una red
TCP/IP, el dominio de comunicación será AF_INET.
Cabe aclarar que existen otros dominios de comunicación.
Los sockets no se han diseñado solamente para TCP/IP. La idea original fue que se usase la misma
interfaz también para distintas familias de protocolos.
Tipos de Sockets
Hay varios tipos de sockets, están las direcciones de Internet DARPA (sockets de Internet), nombres
de ruta en un nodo local (sockets de Unix), direcciones CCITT X.25 (sockets X.25). Este trabajo está
basado en el primero: Sockets de Internet pertenecientes al dominio AF_INET.
2|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Los dos tipos de sockets de Internet más usados son los “Stream Sockets” (Sockets de Flujo) y
“Datagram Sockets” (Sockets de Datagramas) a los que nos referiremos como “SOCK_STREAM” y
“SOCK_DGRAM”, respectivamente. Los SOCK_DGRAM son a veces llamados “sockets sin conexión”.
Tipos de sockets en el dominio AF_INET
•
•
•
Sockets Stream.
Sockets Datagram.
Sockets Raw.
Sockets Stream :
Son los más utilizados, hacen uso del protocolo TCP el cual nos provee un flujo de datos
bidireccional, secuenciado, sin duplicación de paquetes y libre de errores.
Sockets Datagram:
Hacen uso del protocolo UDP, el cual nos provee un flujo de datos bidireccional, pero los paquetes
pueden llegar fuera de secuencia o pueden no llegar. Por lo tanto el proceso que recibe los datos debe
realizar reordenamiento, eliminar duplicados y asegurar la confiabilidad. Se llaman también sockets
sin conexión, porque no hay que mantener una conexión activa, como en el caso de sockets stream.
Son utilizados para transferencia de información paquete por paquete. Como Ejemplos de aplicación
de estos son: dns, tftp, bootp, etc.
Sockets raw:
No son para el usuario más común, son provistos principalmente para aquellos interesados en
desarrollar nuevos protocolos de comunicación o para hacer uso de facilidades ocultas de un protocolo
existente.
Estructuras de Datos usadas
La estructura general para el almacenamiento de direcciones de sockets es la estructura SOCKADDR:
struct sockaddr {
unsigned short
sa_family; // familia de direcciones, AF_xxx
char
sa_data[14]; // 14 bytes de la dirección del protocolo
};
3|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Esta estructura solo posee un campo de definición del tipo de socket y espacio suficiente para el
almacenamiento de cualquier dirección conocida.
En nuestro caso solo utilizaremos sockets de internet, por lo que resulta conveniente la utilización de
la estructura SOCKADDR_IN que en realidad es una redefinición de la anterior.
struct sockaddr_in {
short int
sin_family;
// Dominio de la dirección.
unsigned short int
sin_port;
// Número de Puerto.
struct in_addr
sin_addr;
// Direccion de Internet.
unsigned char
sin_zero[8];
// Compatibilidad.
};
Esta estructura facilita la referencia a cada elemento de dirección de socket, como son la IP y el
puerto. Notar que sin_zero es incluido para acomodar la estructura al largo de STRUCT SOCKADDR
que es una estructura anteriormente usada y por ende debe ser establecido a todos los ceros (zeros)
con la función memset().
Además un puntero a STRUCT SOCKADDR_IN puede lanzar un puntero a STRUCT SOCKADDR y
vise-versa. Así que si socket() necesita un STRUCT SOCKADDR*, se puede aún usar STRUCT
SOCKADDR_ IN* usando un casting del tipo de datos. En esta estructura, SIN_PORT y SIN_ADDR
deben ser Network Byte Order (NBO).
Luego la estructura IN_ADRR se define como:
struct in_addr {
unsigned long
s_addr;
// Direccion IP (4 Bytes)
};
Por lo tanto si definimos:
struct sockaddr_in
myAdd;
4|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
myAdd.sin_addr.s_addr haría referencia a una dirección IP de 4 bytes (en NBO).
Conversión de Órdenes – NBO/HBO
HBO - Host Byte Order
NBO – Network Byte Order
Ambos términos se refieren a la forma de almacenar los datos en la memoria de host o al orden en
que los datos son emitidos al medio de comunicación (Big Endian o Little Endian).
Existen funciones de C que se encargan de ajustar las diferencias que pudieran existir entre los
ordenes de los bytes en el host y la red. Hay dos tipos que se pueden convertir: short (2 bytes) y long
(4 bytes):
htons()
“Host to network Short”
htonl()
“Host to network Long”
ntohs()
“Network to Host Short”
ntohl()
“Network to Host Long”
SIN_ADDR y SIN_PORT necesitan estar en NBO en STRUCT SOCKADDR_IN, pero SIN_FAMILY no.
Esto se debe a que SIN_ADDR y SIN_PORT son encapsulados en el paquete en las capas IP y UDP,
respectivamente (entonces deben estar en el orden que la red los espera); mientras que el campo
SIN_FAMILY es sólo usado por el kernel para determinar qué tipo de dirección contiene la estructura,
así que debe estar en HBO.
Es importante recordar poner los bytes en NBO antes de ponerlos en la Red ya que, entre otras
cosas, asegura la portabilidad del programa creado bajo un sistema operativo dado.
Manejo de direcciones IP
Existen funciones que permiten el manejo de direcciones IP, la función inet_addr(), convierte
una dirección IP dada en la notación de cifras y puntos en un unsigned long. La asignación se puede
hacer así:
ina.sin_addr.s_addr = inet_addr("172.31.1.7");
5|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Es de notar que inet_addr() ya devuelve la dirección según la Ordenación de bytes de la red por
lo que no es necesario llamar a htonl().
Llamadas al sistema (System Calls)
Los sistemas operativos tradicionalmente proporcionan una interfase para que las aplicaciones de
espacio de usuario puedan comunicarse con el hardware. Esta interfase son las system calls,
conocidas en Linux simplemente como syscalls. Mediante estas llamadas, las aplicaciones podrán
pedir al sistema operativo que realice tareas en su nombre. Por ejemplo, la función open() emitida por
un proceso de usuario, estará indicando al kernel que abra algún archivo, el kernel que es el único con
potestad para acceder al hardware (en este caso el disco), realizará la apertura del archivo que la
aplicación le haya indicado en sus parámetros, es decir, el kernel se ejecutará en nombre del proceso
de usuario, realizando la tarea que le ha sido pedida.
En realidad, las llamadas al sistema son casi el único punto de entrada que tienen los procesos de
espacio de usuario al kernel. Es el principal mecanismo de comunicación de las aplicaciones con el
kernel.
El puente AP I / Syscall
Para que nuestra aplicación de espacio de usuario pueda emitir una syscall, es necesario poder
realizar la llamada mediante un API que alguien nos proporcione. Este API lo proporciona la librería
estándar de C de nuestro sistema.
En la siguiente figura podemos ver la relación existente entre las aplicaciones, la librería de C y la
llamada al kernel para la función “printf()” en un sistema operativo Linux.
Las llamadas al sistema nos permiten el establecimiento de un socket en cada uno de los procesos y
la comunicación transparente entre ellos a través de la red que comparten.
socket()
Para obtener el descriptor antes mencionado se debe una llamada a la rutina de sistema (syscall)
socket(). Ésta devuelve el descriptor del socket con el cual es posible establecer comunicación
entre procesos usando las funciones send() y recv(). Dado que es un descriptor también se
6|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
pueden usar las funciones read() y write() para comunicarse a través del socket pero send() y
recv() ofrecen un mejor control sobre transmisión de datos.
La sintaxis de esta función es:
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Los argumentos de la función socket() son:
•
•
•
domain es un "AF_INET", igual que en la estructura struct sochaddr_in de arriba.
type le dice al kernel qué tipo de socket es (SOCK_STREAM o SOCK_DGRAM)
protocol se le asigna un "0" para que socket() elija el protocolo correcto en función del tipo(type).
Hay muchos más dominios (domain) y tipos (type) de los que se han listado. Además, hay una
manera mejor de obtener el protocolo (protocol). La función socket() sólo devuelve un descriptor de
socket que puede usarse en posteriores llamadas al sistema, o -1 en caso de error.
bind()
Una vez que se tiene el socket, se lo puede asociar con algún puerto de la máquina.
(Esto es lo que comúnmente se hace si se va a escuchar [listen()] a la espera de conexiones
entrantes sobre un puerto específico). El kernel usa el número de puerto para asociar los paquetes
entrantes con un descriptor de socket de un cierto proceso. Si solamente se va a hacer un connect()
esto no es necesario.
Sinopsis de llamada al sistema bind() :
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
Los argumentos de la función bind() son:
sockfd es el descriptor de archivo de socket que devolvió socket().
7|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
my_addr es un puntero a una estructura struct sockaddr que contiene información acerca de la
dirección propia, (puerto y dirección IP).
addrlen se puede asignar a sizeof(struct sockaddr) .
bind() devuelve -1 en caso de error
No es recomendable usar números de puerto demasiado pequeños. Todos los puertos por debajo
del 1024 están RESERVADOS(salvo para el superusuario). Se puede usar cualquier número de puerto
por encima del 1024, hasta el 65535(siempre y cuando no lo esté usando otro programa).
Puede ocurrir que al volver a ejecutar bind() en un servidor se obtenga el error "Address already in
use". Esto significa que parte de un socket que estuvo conectado, está todavía colgando en el núcleo y
está bloqueando el puerto. Se puede esperar a que se libere (alrededor de un minuto) o añadir código
permitiendo reutilizar el puerto.
connect()
Se utiliza para conectarse a una máquina remota.
Sinopsis de llamada al sistema connect() :
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Los argumentos de la función connect() son:
sockfd es el descriptor de archivo de socket, como lo devolvió la llamada a socket()
serv_addr es una estructura struct sockaddr que contiene el puerto y la dirección IP de destino
addrlen se le puede asignar el valor sizeof(structsockaddr).
Sólo importa el puerto remoto. El núcleo elegirá un puerto local connect() devolverá -1 en caso de
error.
8|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
listen() y accept()
Cuando se desea realizar un servidor, se quiere esperar a que lleguen conexiones entrantes y
gestionarlas de alguna manera. El proceso consta de dos pasos: en primer lugar se escucha
(listen() ) y después se acepta ( accept() ).
listen()
La llamada listen() tiene la siguiente forma:
int listen(int sockfd, int backlog);
•
•
sockfd es un descriptor de archivo de socket
backlog es el número de conexiones permitidas en la cola de entrada.
Las conexiones entrantes van a esperar en esta cola hasta que se las acepte (accept() ) y éste es
el límite de conexiones que puede haber en cola.
Se necesita llamar a bind() antes de poder llamar a listen(), de lo contrario el kernel dejará
escuchando al programa en un puerto aleatorio. Por lo tanto para estar a la espera de conexiones
entrantes, la secuencia de llamadas que corresponde hacer es:
socket();
bind();
listen();
accept()
La llamada al sistema accept() permite aceptar una conexión entrante a un puerto en el que estamos
escuchando, cuando un host remoto intente establecer una conexión mediante connect().
Cuando el host remoto ejecuta connect su conexión pasará a cola, esperando a ser aceptada.
Cuando se llama a accept() esta obtiene la primera conexión pendiente de la cola y devolverá un
socket nuevo para usar en esta nueva conexión. El original estará todavía escuchando en el puerto, y
el de nueva creación estará listo para enviar (send()) y recibir (recv()).
9|P ági na
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
La llamada es como sigue:
#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
•
•
•
sockfd es el descriptor de archivo donde se está escuchando (listen())
addr es un puntero a una estructura struct sockaddr_in local, donde se guardará la
información de la conexión entrante (con la cual se puede averiguar que máquina está llamando, y
desde qué puerto)
addrlen es un puntero a una variable local int a la que se debe asignar el valor de sizeof(struct
sockaddr_in)
.
send() y recv()
Estas dos funciones sirven para comunicarse a través de sockets de flujo o sockets de datagramas
conectados.
La llamada al sistema send() es:
int send(int sockfd, const void *msg, int len, int flags);
•
•
•
•
sockfd es el descriptor de socket al que se quiere enviar datos (puede ser el devuelto por
socket(), o bien el devuelto por accept().)
msg es un puntero a los datos a enviar
len es la longitud de esos datos en bytes
flags lleva normalmente el valor 0, y sirve para establecer opciones.
La llamada send() devuelve el número de bytes que se enviaron en realidad, lo que sirve para
detectar errores.
La llamada al sistema recv() es similar en muchos aspectos:
int recv(int sockfd, void *buf, int len, unsigned int flags);
10 | P á g i n a
TP4 – Sockets TCP/UDP
•
•
•
•
66.48 - Seminario de Redes de Computadoras
sockfd es el descriptor del archivo del que se va a leer
buff es el buffer donde se va a depositar la información leída
len es la longitud máxima del buffer
flags nuevamente son indicaciones
Como antes, recv() devuelve el número de bytes que se leyeron en realidad, o -1 en caso de error (y
establece errno apropiadamente). Si recv() devuelve 0, significa que la máquina remota ha cerrado
su conexión.
sendto() y recvfrom()
Estas funciones sirven para el envío y recepción de datagramas sobre sockets UDP.
Puesto que los sockets de datagramas no están conectados a una máquina remota, solo se necesita
pasarle a las llamadas la dirección de destino:
int sendto(int sockfd, const void *msg, int len, unsigned int flags,
const struct sockaddr *to, int tolen);
Como se puede ver, esta llamada es básicamente la misma que send()añadiendo dos items más de
información:
•
•
to es un puntero a una estructura struct sockaddr, que contiene la dirección IP y el puerto de
destino
tolen es la longitud de to, se le asigna el valor sizeof(struct sockaddr).
Lo mismo que send(), sendto() devuelve el número de bytes que realmente se enviaron (que, igual
que antes, podrían ser menos de los que se enviaron)
La misma semejanza presentan recv() y recvfrom(). La sinopsis de recvfrom() es:
int recvfrom(int sockfd, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
Los campos from y fromlen son similares a to y tolen de sendto.
11 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
close() y shutdown()
Se utilizan para cerrar la conexión del descriptor de socket. Sólo hay que usar la función close() que
cierra descriptores de archivo: close(sockfd);
Esto impedirá más lecturas y escrituras al socket. Cualquiera que intente leer o escribir sobre el
socket desde el extremo remoto recibirá un error.
Si se desea un poco más de control sobre cómo se cierra el socket se puede usar la función
shutdown() que permite cortar la comunicación en un sentido, o en los dos (como lo hace close()).
Sinopsis de la llamada al sistema shutdown:
int shutdown(int sockfd, int how);
sockfd es el descriptor de socket que se desea desconectar, y how puede tener uno de los siguientes
valores:
0 -- No se permite recibir más datos
1 -- No se permite enviar más datos
2 -- No se permite enviar ni recibir más datos (similar a close())
shutdown() devuelve 0 si tiene éxito, y -1 en caso de error
Si se usa shutdown() en un datagram socket, simplemente inhabilitará el socket para posteriores
llamadas a send() y recv()
shutdown() no cierra realmente el descriptor de archivo, sólo cambia sus condiciones de uso. Para
liberar un descriptor de socket es necesario usar close().
Particularidades en la portabilidad de código Unix a Windows:
Para que una aplicación creada para Unix corra bajo un sistema operativo Windows se debe:
1- Incluir la librería winsock
2- Hacer una llamada a WSAStartup() antes de hacer algo con la
Librería de Sockets.
El código para hacer esto:
12 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
#include <winsock.h>
{
WSAData wsaData;
If (WSAStartup{MAKEWORD(1, 1), &wsaData} != 0) {
Fprintf(stderr, “WSAStartup failed.\n”);
Exit(1);
}
WSAStarup: Se debe llamar a esta función antes de llamar a cualquiera otra de winsock. Nos
permite especificar que versión de la API de Windows socket va a necesitar nuestro programa. Se
establece una negociación entre la aplicación y Winsock.dll
WSCleanup() termina sesion desde los DLL subyacentes de winsock.
13 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Modelo Cliente-Servidor
Este es un mundo cliente-servidor. Casi cualquier cosa en la red tiene que ver con procesos
clientes que dialogan con procesos servidores y viceversa. Consideremos telnet, por ejemplo.
Cuando nos conectamos al puerto 23 de una máquina remota mediante telnet (el cliente) un
programa de aquella máquina (llamado telnetd, el servidor) despierta a la vida. Gestiona la
conexión telnet entrante, presenta una pantalla de login, etc.
Figura 1. Interacción Cliente-Servidor.
El intercambio de información entre cliente y servidor se resume en la Figura 1. En ella se puede
observar que el par cliente-servidor pueden hablar SOCK_STREAM , SOCK_DGRAM o cualquier otra cosa
(siempre y cuando los dos hablen lo mismo). Algunos buenos ejemplos de parejas cliente-servidor son
telnet/telnetd , ftp/ftpd, o bootp/bootpd. Cada vez que usamos ftp, hay un programa remoto, ftpd,
que nos sirve.
Con frecuencia, solamente habrá un servidor en una máquina determinada, que atenderá a
múltiples clientes usando fork(). El funcionamiento básico es: el servidor espera una
conexión, la acepta (accept()) y usa fork() para obtener un proceso hijo que la atienda. Eso
es lo que hace nuestro servidor de ejemplo en la siguiente sección.
En realidad no hay demasiado que contar aquí, así que sólo presentaré un par de
programas de ejemplo: talker.c y listener.c.
listener se sienta a esperar en la máquina hasta que llega un paquete al puerto 4950. talker
envía un paquete a ese puerto en la máquina indicada que contiene lo que el usuario haya
escrito en la línea de comandos.
Código fuente del servidor “listener.c”:
/*
** listener.c -- Ejemplo de servidor de sockets de datagramas
*/
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<unistd.h>
<errno.h>
<string.h>
<sys/types.h>
14 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MYPORT 4950
// puerto al que conectarán los clientes
#define MAXBUFLEN 100
int main(void)
{
int sockfd;
struct sockaddr_in my_addr;
// información sobre mi dirección
struct sockaddr_in their_addr; // información sobre la dirección del cliente
int addr_len, numbytes;
char buf[MAXBUFLEN];
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(my_addr.sin_zero), '\0', 8);
//
//
//
//
Ordenación de bytes de máquina
short, Ordenación de bytes de la red
rellenar con mi dirección IP
poner a cero el resto de la estructura
if (bind(sockfd, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
if ((numbytes=recvfrom(sockfd,buf, MAXBUFLEN-1, 0,
(struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '\0';
printf("packet contains \"%s\"\n",buf);
close(sockfd);
return 0;
}
Observar que en nuestra llamada a socket() finalmente estamos usando SOCK_DGRAM.
Observa también que no hay necesidad de escuchar (listen()) o aceptar (accept()). ¡Esa
es una de las ventajas de usar sockets de datagramas sin conexión!
A continuación el código fuente del cliente talker.c
15 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
/*
** talker.c -- ejemplo de cliente de datagramas
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<unistd.h>
<errno.h>
<string.h>
<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<arpa/inet.h>
<netdb.h>
#define MYPORT 4950
// puerto donde vamos a conectarnos
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in their_addr; // información sobre la dirección del servidor
struct hostent *he;
int numbytes;
if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { //obtener información de máquina
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET;
// Ordenación de bytes de máquina
their_addr.sin_port = htons(MYPORT); // short, Ordenación de bytes de la red
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // poner a cero el resto de la estructura
if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
perror("sendto");
exit(1);
}
printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(their_addr.sin_addr));
close(sockfd);
return 0;
}
16 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Para compilar utilizamos el comando gcc listener.c utilizando un sistema operativo
Linux CentOS 5. Esto genera un archivo a.out el cual lo renombramos a listener.
Procedimos de manera análoga para el cliente (talker). ¡Y esto es todo! Ejecutamos listener
(./listener) en una máquina y luego llama a talker en otra.
Para terminar, cabe hacer la siguiente aclaración. Supongamos que talker llama a
connect() e indica la dirección de listener. A partir de ese momento, talker solamente
puede enviar a y recibir de la dirección especificada en connect(). Por ese motivo no tienes
que usar sendto() y recvfrom(); tienes que usar simplemente send() y recv().
A continuación se muestra la captura del paquete UDP:
17 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
El escenario es muy simple:
Hub
Listener
Talker
172.31.1.7
172.31.1.23
Para conseguir dicha captura se ejecutó el comando ./listener desde una terminal de la
máquina cuya dirección IP es 172.31.1.7 y luego se ejecuta el comando ./talker
172.31.1.7 hola_mundo desde la PC “Talker”. La captura se hizo con el software Wireshark
desde la PC Listener.
18 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Cliente Servidor en TCP
El cliente debe ser ejecutado de manera que pase como argumento la direccion destino y un numero
entero cualquiera. Ejemplo ./cliente localhost 123. El cliente se contactara con el destino y le pasara
ese numero. El servidor que previamente ejecute como ./servidor recibira ese numero y le devolvera al
cliente si es un numero par o impar.
Código fuente del servidor “servidor.c” TCP:
/*
Nombre Archivo: servidor.c
Archivos relacionados: cliente_tcp.c
Fecha: Enero 2008
Compilacion: gcc -Wall servidor_tcp.c -o servidor_tcp
Ejecucion: ./servidor_tcp
Sistema que indica si un numero es par o impar.
Sistema basado en sockets tipo internet en modo conexion.
El servidor sigue una estrategia servidor padre.
El padre imprime el identificador del proceso que escucha en el puerto
y lo identificadores de los procesos que proporcionan el servicio.
*/
#include
#include
#include
#include
#include
#include
#include
#include
<stdlib.h>
<stdio.h>
<unistd.h>
<signal.h>
<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<netdb.h>
#define
PUERTO
12345
/* numero puerto arbitrario */
char
resp;
/* para mandar al cliente */
char
*mensaje;
int
pet;
/* para guardar lo recibido por el cliente
*/
int
sd, sd2;
/* descriptores de sockets */
int
addrlen;
/* lomgitud direcciones */
struct sockaddr_in
server, cliente;/* direcciones sockets servidor y cliente */
/* procedimiento de aborte del servidor, si llega una senal SIGINT */
/* ( <ctrl> <c> ) se cierra el socket y se aborta el programa
*/
void aborta()
{
printf("....abortando el proceso servidor \n");
close(sd);
19 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
close(sd2);
exit(1);
}
/* ---------------- FUNCION MAIN -------------------------------------*/
int main()
{
/* activando la senal SIGINT */
signal(SIGINT, aborta);
/* obtencion de un socket tipo internet */
if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* asignar direcciones en la estructura de direcciones */
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
/* INADDR_ANY=0x000000 = yo mismo */
server.sin_port = htons(PUERTO);
/* convirtiendo a formato red */
/* asociando del socket al numero de puerto */
if ( bind(sd, (struct sockaddr *)&server, sizeof(server)) == -1) {
perror("bind");
exit(1);
}
/* ponerse a escuchar a traves del socket */
if (listen(sd, 5) == -1) {
perror("listen");
exit(1);
}
/* imprimiendo id del proceso padre que espera conexiones */
printf("\n");
printf("\n");
printf("======================================================.\n");
printf("Iniciando Servidor_tcp ....<Control>+<C> para terminar.\n");
printf("======================================================.\n");
printf("Proceso padre %d escuchando en puerto %d \n",getpid(), PUERTO);
printf("\n");
/* se entra al ciclo de escucha y peticion */
printf ("Esperando que un cliente solicite un servicio\n");
while(1) {
/* esperando que un cliente solicite un servicio */
/* sd2:descriptor para hablar con el cliente. El sd corresponde al servicio y
solo
sirve para encolar a los clientes.
En la estructura cliente se cargaran los datos del cliente que inicia la
conexion */
addrlen = sizeof(cliente); /* necesario para la funcion accept */
20 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
if ( (sd2 = accept(sd, (struct sockaddr *)&cliente, &addrlen)) == -1) {
perror("accept");
exit(1);
}
/* se crea un hijo para atender la conexion */
if ( fork() == 0) {
/* tomar un mensaje del cliente
en pet se guardara la informacion recibida; en este caso pet sera un int
donde
guardamos el puerto recibido */
if ( recv(sd2, &pet, sizeof(pet), 0) == -1) {
perror("recv");
exit(1);
}
/* imprimiendo el id del proceso que proporcioan el servicio */
printf("\tProceso %d atendiendo el servicio \n",getpid());
/* proporcionando el servicio */
if ((pet % 2) == 0) resp='p';
else resp='i';
/* enviando la respuesta del servicio */
if ( send(sd2, &resp, sizeof(resp), 0) == -1) {
perror("send");
exit(1);
}
/* cerrando el canal privado de comunicacion */
close(sd2);
/* termina ejecucion proceso hijo */
exit(0);
}
}
/* cerrando el canal de conexion */
close(sd);
/* adios, recordemos que el main es una funcion */
return 0;
}
Código fuente del cliente “cliente.c” TCP:
/*
Nombre Archivo: cliente_tcp.c
Archivos relacionados: servidor_tcp.c
Fecha: Enero 2008
Compilacion: gcc -Wall cliente_tcp.c -o cliente_tcp
Ejecucion: cliente_tcp <host> <numero>
Ejemplo:
./cliente_tcp localhost 12345
Sistema que indica si un numero es par o impar.
Sistema basado en sockets tipo internet en modo conexion.
*/
21 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
#include
#include
#include
#include
#include
#include
#include
<stdlib.h>
<stdio.h>
<unistd.h>
<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<netdb.h>
#define
PUERTO
12345
/* numero puerto arbitrario */
int main(int argc, char *argv[])
{
char
resp;
int
pet;
int
sd;
struct hostent
*hp;
struct sockaddr_in
pin;
char
*host;
/* parametro entrada */
/* parametro de salida */
/* descriptor de socket
*/
/* estructura del host
*/
/* direcciones socket
*/
/* nombre del host */
/* verificando el paso de parametros */
if ( argc != 3) {
fprintf(stderr,"uso: %s <host> <numero> \n",argv[0]);
fprintf(stderr,"Ejemplo:\n");
fprintf(stderr,"
./cliente localhost 123 \n");
exit(1);
}
/* tomando el nombre del host de los argumentos de la linea de comandos */
host = argv[1];
/* encontrando todo lo referente acerca de la maquina host */
if ( (hp = gethostbyname(host)) == 0) {
perror("gethosbyname");
exit(1);
}
/* llenar la estructura de direcciones con la informacion del host */
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
pin.sin_port = htons(PUERTO);
/* obtencion de un socket tipo internet */
if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* conectandose al PUERTO en el HOST */
if ( connect(sd, (struct sockaddr *)&pin, sizeof(pin)) == -1) {
perror("connect");
exit(1);
}
/* enviar mensaje al PUERTO del servidor en la maquina HOST */
pet = atoi(argv[2]); /*cargo en pet el parametro pasado a la entrada*/
if ( send(sd, &pet, sizeof(pet), 0) == -1 ) {
perror("send");
exit(1);
}
22 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
/* esperar por la respuesta */
if ( recv(sd, &resp, sizeof(resp), 0) == -1 ) {
perror("recv");
exit(1);
}
/* imprimir los resultados */
printf("El numero %d es ",pet );
if (resp == 'i') printf("impar \n");
else printf("par \n");
/* cerrando el socket */
close(sd);
/* adios, recordemos que main es una funcion */
return 0;
}
23 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
A continuación se muestra las capturas hechas con el Wireshark:
No.
Time
Source
Destination
1
0.000000
127.0.0.1
127.0.0.1
12345 [SYN] Seq=0 Len=0 MSS=16396 TSV=77339 TSER=0 WS=5
Protocol Info
TCP
40227 >
Frame 1 (74 bytes on wire, 74 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 0, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 3c 79 dd 40 00 40 06 c2 dc 7f 00 00 01 7f 00
.<y.@.@.........
24 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0020
00 01 9d 23 30 39 d3 14 57 c6 00 00 00 00 a0 02
...#09..W.......
0030
80 18 69 3b 00 00 02 04 40 0c 04 02 08 0a 00 01
..i;....@.......
0040
2e 1b 00 00 00 00 01 03 03 05
..........
No.
Time
Source
Destination
Protocol Info
2 0.000014
127.0.0.1
127.0.0.1
TCP
12345 >
40227 [SYN, ACK] Seq=0 Ack=1 Win=1048576 Len=0 MSS=16396 TSV=77339 TSER=77339 WS=5
Frame 2 (74 bytes on wire, 74 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 40227 (40227),
Seq: 0, Ack: 1, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 3c 00 00 40 00 40 06 3c ba 7f 00 00 01 7f 00
.<..@.@.<.......
0020
00 01 30 39 9d 23 d2 d5 80 c2 d3 14 57 c7 a0 12
..09.#......W...
0030
80 00 e7 8d 00 00 02 04 40 0c 04 02 08 0a 00 01
........@.......
0040
2e 1b 00 01 2e 1b 01 03 03 05
..........
No.
Time
Source
Destination
3 0.000026
127.0.0.1
127.0.0.1
12345 [ACK] Seq=1 Ack=1 Win=32800 Len=0 TSV=77339 TSER=77339
Protocol Info
TCP
40227 >
Frame 3 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
25 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 1, Ack: 1, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 79 de 40 00 40 06 c2 e3 7f 00 00 01 7f 00
.4y.@.@.........
0020
00 01 9d 23 30 39 d3 14 57 c7 d2 d5 80 c3 80 10
...#09..W.......
0030
04 01 cc af 00 00 01 01 08 0a 00 01 2e 1b 00 01
................
0040
2e 1b
..
No.
Time
Source
Destination
Protocol Info
4 0.000715
127.0.0.1
127.0.0.1
TCP
40227 >
12345 [PSH, ACK] Seq=1 Ack=1 Win=32800 [TCP CHECKSUM INCORRECT] Len=4 TSV=77339
TSER=77339
Frame 4 (70 bytes on wire, 70 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 1, Ack: 1, Len: 4
Data (4 bytes)
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 38 79 df 40 00 40 06 c2 de 7f 00 00 01 7f 00
.8y.@.@.........
0020
00 01 9d 23 30 39 d3 14 57 c7 d2 d5 80 c3 80 18
...#09..W.......
0030
04 01 fe 2c 00 00 01 01 08 0a 00 01 2e 1b 00 01
...,............
0040
2e 1b 7b 00 00 00
..{...
No.
Time
Source
Destination
Protocol Info
26 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
5 0.000808
127.0.0.1
127.0.0.1
40227 [ACK] Seq=1 Ack=5 Win=32768 Len=0 TSV=77339 TSER=77339
TCP
12345 >
Frame 5 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 40227 (40227),
Seq: 1, Ack: 5, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 ae d8 40 00 40 06 8d e9 7f 00 00 01 7f 00
.4..@.@.........
0020
00 01 30 39 9d 23 d2 d5 80 c3 d3 14 57 cb 80 10
..09.#......W...
0030
04 00 cc ac 00 00 01 01 08 0a 00 01 2e 1b 00 01
................
0040
2e 1b
..
No.
Time
Source
Destination
Protocol Info
6 0.001274
127.0.0.1
127.0.0.1
TCP
12345 >
40227 [PSH, ACK] Seq=1 Ack=5 Win=32768 [TCP CHECKSUM INCORRECT] Len=1 TSV=77340
TSER=77339
Frame 6 (67 bytes on wire, 67 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 40227 (40227),
Seq: 1, Ack: 5, Len: 1
Data (1 byte)
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 35 ae d9 40 00 40 06 8d e7 7f 00 00 01 7f 00
.5..@.@.........
0020
00 01 30 39 9d 23 d2 d5 80 c3 d3 14 57 cb 80 18
..09.#......W...
27 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0030
04 00 fe 29 00 00 01 01 08 0a 00 01 2e 1c 00 01
...)............
0040
2e 1b 69
..i
No.
Time
Source
Destination
Protocol Info
7 0.001286
127.0.0.1
127.0.0.1
12345 [ACK] Seq=5 Ack=2 Win=32800 Len=0 TSV=77340 TSER=77340
TCP
40227 >
Frame 7 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 5, Ack: 2, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 79 e0 40 00 40 06 c2 e1 7f 00 00 01 7f 00
.4y.@.@.........
0020
00 01 9d 23 30 39 d3 14 57 cb d2 d5 80 c4 80 10
...#09..W.......
0030
04 01 cc a8 00 00 01 01 08 0a 00 01 2e 1c 00 01
................
0040
2e 1c
..
No.
Time
Source
Destination
Protocol Info
8 0.001772
127.0.0.1
127.0.0.1
TCP
12345 [FIN, ACK] Seq=5 Ack=2 Win=32800 Len=0 TSV=77340 TSER=77340
40227 >
Frame 8 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 5, Ack: 2, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
28 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0010
00 34 79 e1 40 00 40 06 c2 e0 7f 00 00 01 7f 00
.4y.@.@.........
0020
00 01 9d 23 30 39 d3 14 57 cb d2 d5 80 c4 80 11
...#09..W.......
0030
04 01 cc a7 00 00 01 01 08 0a 00 01 2e 1c 00 01
................
0040
2e 1c
..
No.
Time
Source
Destination
Protocol Info
9 0.041379
127.0.0.1
127.0.0.1
40227 [ACK] Seq=2 Ack=6 Win=32768 Len=0 TSV=77350 TSER=77340
TCP
12345 >
Frame 9 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 40227 (40227),
Seq: 2, Ack: 6, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 ae da 40 00 40 06 8d e7 7f 00 00 01 7f 00
.4..@.@.........
0020
00 01 30 39 9d 23 d2 d5 80 c4 d3 14 57 cc 80 10
..09.#......W...
0030
04 00 cc 9e 00 00 01 01 08 0a 00 01 2e 26 00 01
.............&..
0040
2e 1c
..
No.
Time
Source
Destination
Protocol Info
10 7.872108
127.0.0.1
127.0.0.1
TCP
40227 [FIN, ACK] Seq=2 Ack=6 Win=32768 Len=0 TSV=79307 TSER=77340
12345 >
Frame 10 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 40227 (40227),
Seq: 2, Ack: 6, Len: 0
29 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 ae db 40 00 40 06 8d e6 7f 00 00 01 7f 00
.4..@.@.........
0020
00 01 30 39 9d 23 d2 d5 80 c4 d3 14 57 cc 80 11
..09.#......W...
0030
04 00 c4 f8 00 00 01 01 08 0a 00 01 35 cb 00 01
............5...
0040
2e 1c
..
No.
Time
Source
Destination
Protocol Info
11 7.872211
127.0.0.1
127.0.0.1
12345 [ACK] Seq=6 Ack=3 Win=32800 Len=0 TSV=79307 TSER=79307
TCP
40227 >
Frame 11 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 40227 (40227), Dst Port: 12345 (12345),
Seq: 6, Ack: 3, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 00 00 40 00 40 06 3c c2 7f 00 00 01 7f 00
.4..@.@.<.......
0020
00 01 9d 23 30 39 d3 14 57 cc d2 d5 80 c5 80 10
...#09..W.......
0030
04 01 bd 48 00 00 01 01 08 0a 00 01 35 cb 00 01
...H........5...
0040
35 cb
5.
No.
Time
Source
Destination
Protocol Info
12 7.872660
127.0.0.1
127.0.0.1
TCP
49814 [FIN, ACK] Seq=0 Ack=0 Win=1024 Len=0 TSV=79307 TSER=1955
12345 >
Frame 12 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 49814 (49814),
Seq: 0, Ack: 0, Len: 0
30 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 09 1d 40 00 40 06 33 a5 7f 00 00 01 7f 00
.4..@.@.3.......
0020
00 01 30 39 c2 96 9d 11 0e bc 9c 2e 01 bf 80 11
..09............
0030
04 00 fa bf 00 00 01 01 08 0a 00 01 35 cb 00 00
............5...
0040
07 a3
..
No.
Time
Source
13 7.872775
127.0.0.1
12345 [RST] Seq=0 Len=0
Destination
Protocol Info
127.0.0.1
TCP
49814 >
Frame 13 (54 bytes on wire, 54 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 49814 (49814), Dst Port: 12345 (12345),
Seq: 0, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 28 00 00 40 00 40 06 3c ce 7f 00 00 01 7f 00
.(..@.@.<.......
0020
00 01 c2 96 30 39 9c 2e 01 bf 00 00 00 00 50 04
....09........P.
0030
00 00 21 21 00 00
..!!..
No.
Time
Source
Destination
Protocol Info
14 7.872963
127.0.0.1
127.0.0.1
TCP
49815 [FIN, ACK] Seq=0 Ack=0 Win=1024 Len=0 TSV=79308 TSER=7743
12345 >
Frame 14 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 49815 (49815),
Seq: 0, Ack: 0, Len: 0
31 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 39 5b 40 00 40 06 03 67 7f 00 00 01 7f 00
.49[@.@..g......
0020
00 01 30 39 c2 97 00 d6 27 68 01 4b ab 02 80 11
..09....'h.K....
0030
04 00 59 51 00 00 01 01 08 0a 00 01 35 cc 00 00
..YQ........5...
0040
1e 3f
.?
No.
Time
Source
15 7.872996
127.0.0.1
12345 [RST] Seq=0 Len=0
Destination
Protocol Info
127.0.0.1
TCP
49815 >
Frame 15 (54 bytes on wire, 54 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 49815 (49815), Dst Port: 12345 (12345),
Seq: 0, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 28 00 00 40 00 40 06 3c ce 7f 00 00 01 7f 00
.(..@.@.<.......
0020
00 01 c2 97 30 39 01 4b ab 02 00 00 00 00 50 04
....09.K......P.
0030
00 00 12 c0 00 00
......
No.
Time
Source
Destination
Protocol Info
16 7.873014
127.0.0.1
127.0.0.1
TCP
49818 [FIN, ACK] Seq=0 Ack=0 Win=1024 Len=0 TSV=79308 TSER=54551
12345 >
Frame 16 (66 bytes on wire, 66 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 12345 (12345), Dst Port: 49818 (49818),
Seq: 0, Ack: 0, Len: 0
32 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 34 0c 48 40 00 40 06 30 7a 7f 00 00 01 7f 00
.4.H@.@.0z......
0020
00 01 30 39 c2 9a 99 1f d9 53 98 a2 3f 16 80 11
..09.....S..?...
0030
04 00 2c d5 00 00 01 01 08 0a 00 01 35 cc 00 00
..,.........5...
0040
d5 17
..
No.
Time
Source
17 7.873021
127.0.0.1
12345 [RST] Seq=0 Len=0
Destination
Protocol Info
127.0.0.1
TCP
49818 >
Frame 17 (54 bytes on wire, 54 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00
(00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 49818 (49818), Dst Port: 12345 (12345),
Seq: 0, Len: 0
0000
00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
..............E.
0010
00 28 00 00 40 00 40 06 3c ce 7f 00 00 01 7f 00
.(..@.@.<.......
0020
00 01 c2 9a 30 39 98 a2 3f 16 00 00 00 00 50 04
....09..?.....P.
0030
00 00 e7 51 00 00
...Q..
33 | P á g i n a
TP4 – Sockets TCP/UDP
66.48 - Seminario de Redes de Computadoras
Conclusión:
Los sockets ayudan a los procesos de aplicación a comunicarse entre sí utilizando descriptors de archive
estándar en Unux. Los dos tipos de sockets de Internet utilizados son: SOCK_STREAM (TCP) y
SOCK_DGRAM (UDP). Existen numerosas rutinas para facilitar el proceso de comunicación.
Referencias:
Libros:
•
•
Unix Network Programming, volumes 1-2 by W. Richard Stevens.
TCP/IP Illustrated, volumes 1-3 by W. Richard Stevens and Gary R. Wright
Recursos Web:
•
•
Beej's Guide to Network Programming www.ecst.csuchico.edu/beej/guide/net
http://www.arrakis.es/~dmrq/beej/clientserver.html
34 | P á g i n a
Descargar