Ejemplos de Sockets AF_INET en C: Stream (TCP) y Datagrama (UDP)
Ejemplo de programa cliente TCP (AF_INET, SOCK_STREAM)
Programa cliente de la familia AF_INET y del tipo stream que envía mensajes a un programa servidor. Las funciones leer_linea y escribir_linea están en el fichero comun.c.
void escribir_mensaje(int s);
main(){
int sd;
struct sockaddr_in dirser;
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("Error en la creación del socket");
return 1;
}
dirser.sin_family = AF_INET;
dirser.sin_port = htons(7000);
dirser.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sd, (struct sockaddr*)&dirser, sizeof(dirser)) == -1)
perror("");
else
escribir_mensaje(sd);
close(sd);
}
void escribir_mensaje(int s){
char mens[80], mensa[80];
int nbytes;
puts("Dame un mensaje");
if ((nbytes = read(0, mens, sizeof(mens))) == -1){
perror("Error al leer mensaje de teclado");
}
else {
mens[nbytes - 1] = '\0';
write(s, mens, strlen(mens) + 1);
printf("Mensaje enviado %s\n", mens);
read(s, mensa, sizeof(mensa));
printf("Mensaje recibido %s\n", mensa);
}
}Ejemplo de programa servidor concurrente TCP (AF_INET, SOCK_STREAM)
Programa servidor concurrente de la familia AF_INET y del tipo stream que recibe mensajes de programas clientes, los visualiza y los vuelve a enviar al cliente junto con su PID. Las funciones leer_linea y escribir_linea están en el fichero comun.c. Para terminar el programa.
void recibir_mensaje(int s);
main(){
struct sockaddr_in dirser, dircli; // dirección servidor, cliente
int sd, nsd, longcli, ret, cont = 0, s; // descriptor de socket
longcli = sizeof(dircli);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("Error en la creación del socket");
return 1;
}
dirser.sin_family = AF_INET;
dirser.sin_port = htons(7000);
dirser.sin_addr.s_addr = inet_addr("127.0.0.1");
if (bind(sd, (struct sockaddr *)&dirser, sizeof(dirser)) == -1){
perror("Error al publicar la dirección del servidor");
return 1;
}
if (listen(sd, s) == -1){
perror("Error al crear la cola de atención al cliente");
return 1;
}
while (1){
printf("En espera de conexión PID %d\n", getpid());
if ((nsd = accept(sd, (struct sockaddr*)&dircli, &longcli)) == -1){
perror("Error al recibir la petición del cliente");
}
else {
printf("Conexión aceptada\n");
if ((ret = fork()) == -1){
perror("Error al duplicar proceso");
}
else {
if (ret == 0) {
close(1);
recibir_mensaje(nsd);
printf("Cliente %d atendido\n", cont + 1);
close(nsd);
exit(0);
}
else {
close(nsd);
cont++;
}
}
}
}
}
void recibir_mensaje(int s){
char mens[80], mensa[80];
int nbytes;
if ((nbytes = read(s, mens, sizeof(mens))) == -1){
perror("Error al leer mensaje del cliente");
}
else {
mens[nbytes - 1] = '\0';
printf("Mensaje recibido %s\n", mens);
sprintf(mensa, "%s%d", mens, getpid());
write(s, mensa, strlen(mensa) + 1);
}
}Servidor no orientado a conexión (AF_INET, SOCK_DGRAM)
Servidor interactivo de la familia AF_INET y de tipo datagrama que recibe mensajes de un cliente, los visualiza y los vuelve a enviar junto con el PID del servidor que le atendió (serudp).
main(){
int sd;
struct sockaddr_in dirser, dircli;
char mens[80], mensa[80];
int nb, longd = sizeof(dircli); // longitud dirección
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("Error en la creación del socket");
return 1;
}
dirser.sin_family = AF_INET;
dirser.sin_port = htons(7000);
dirser.sin_addr.s_addr = inet_addr("127.0.0.1");
if (bind(sd, (struct sockaddr *)&dirser, sizeof(dirser)) == -1){
perror("Error al publicar la dirección del servidor");
return 1;
}
if ((nb = recvfrom(sd, mens, sizeof(mens), 0, (struct sockaddr*)&dircli, &longd)) == -1){
perror("Error al recibir");
}
else {
mens[nb - 1] = '\0';
printf("Mensaje recibido %s\n", mens);
sprintf(mensa, "PID servidor %d %s", getpid(), mens);
sendto(sd, mensa, strlen(mensa) + 1, 0, (struct sockaddr *)&dircli, sizeof(dircli));
}
}Cliente UDP (AF_INET, SOCK_DGRAM)
main(){
int sd;
struct sockaddr_in dirser, dircli;
char mens[80], mensa[80];
int nb, longd = sizeof(dircli);
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("Error en la creación del socket");
return 1;
}
dircli.sin_family = AF_INET;
dircli.sin_port = htons(0);
dircli.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");
if (bind(sd, (struct sockaddr *)&dircli, sizeof(dircli)) == -1){
perror("Error al adquirir la dirección del cliente");
return 1;
}
dirser.sin_family = AF_INET;
dirser.sin_port = htons(7000);
dirser.sin_addr.s_addr = inet_addr("127.0.0.1");
puts("Dame mensaje: ");
if ((nb = read(0, mens, sizeof(mens))) == -1){
perror("");
}
else {
mens[nb - 1] = '\0';
sendto(sd, mens, strlen(mens) + 1, 0, (struct sockaddr *)&dirser, sizeof(dirser));
printf("Mensaje enviado %s\n", mens);
if ((nb = recvfrom(sd, mensa, sizeof(mensa), 0, (struct sockaddr*)&dirser, &longd)) == -1){
perror("Error al recibir");
}
else {
mensa[nb - 1] = '\0';
printf("Mensaje recibido del servidor %s\n", mensa);
}
}
}