You are on page 1of 17

Sockets e hilos

Modelos de organizacin de
hilos
a) Modelo del servidor trabajador
b) Modelo de equipo
c) Modelo de entubamiento

Ejemplo: eco con hilos servidor (1/2)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

<fcntl.h>
<string.h>
<stdlib.h>
<errno.h>
<stdio.h>
<netinet/in.h>
<resolv.h>
<sys/socket.h>
<arpa/inet.h>
<unistd.h>
<pthread.h>

void* SocketHandler(void* lp){


int *csock = (int*)lp;
char buffer[TAMBUFER];
int bytecount;
memset(buffer, 0, TAMBUFER);
if((bytecount = recv(*csock, buffer, TAMBUFER, 0))== -1){
free(csock);
fprintf(stderr, "Hilo: error recibiendo datos %d\n", errno);
exit(-1);
}
printf("Hilos: Bytes recibidos %d\nCadena recibida: \"%s\"\n", bytecount, buffer);
strcat(buffer, "Hilos: Eco del servidor: ");
if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
free(csock);
fprintf(stderr, "Hilo: error enviando datos %d\n", errno);
exit(-1);
}

#define PROCESOS 10
#define PUERTO 1101
#define TAMBUFER 1024

printf("Hilos: Bytes enviados %d\n", bytecount);


return 0;
}

Ejemplo: eco con hilos servidor (2/2)


int main(int argv, char** argc){
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(PUERTO);

struct sockaddr_in my_addr, sadr;

memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY ;

int hsock;
int *p_int ;
int err;

if( bind( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){


fprintf(stderr,"Error ligando el socket %d\n",errno);
exit(-1);
}
if(listen( hsock, PROCESOS) == -1 ){
fprintf(stderr, "Error escuchando %d\n",errno);
close(hsock);
exit(-1);
}
//Esperando conexiones
addr_size = sizeof(struct sockaddr_in);

socklen_t addr_size = 0;
int* csock;
pthread_t thread_id=0;

hsock = socket(AF_INET, SOCK_STREAM, 0);


if(hsock == -1){
printf("Error initializando socket %d\n", errno);
exit(-1);
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR,
(char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE,
(char*)p_int, sizeof(int)) == -1 ) ){
printf("Error asignando opciones %d\n", errno);
free(p_int);
exit(-1);
}
free(p_int);

while(1){
printf("Esperando la conexin\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (struct sockaddr*)&sadr, &addr_size))!=
-1){
printf("---------------------\n");
printf("Conexin recibida desde
%s\n",inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
pthread_detach(thread_id);
}
else{
fprintf(stderr, "Error al aceptar una conexin %d\n", errno);
}
}
}

Ejemplo: eco con hilos cliente(1/2)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

<fcntl.h>
<string.h>
<stdlib.h>
<errno.h>
<stdio.h>
<netinet/in.h>
<resolv.h>
<sys/socket.h>
<arpa/inet.h>
<unistd.h>

#define PUERTO 1101


#define DIRECCION "127.0.0.1"
#define TAMBUFER 1024
int main(int argv, char** argc){
struct sockaddr_in my_addr;
char buffer[TAMBUFER];
int bytecount;
int buffer_len=0;
int hsock;
int * p_int;
int err;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error al crear el socket
%d\n",errno);
exit(-1);
}

p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int,
sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int,
sizeof(int)) == -1 ) ){
printf("Error configurando opciones %d\n",errno);
free(p_int);
exit(-1);
}
free(p_int);
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(PUERTO);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = inet_addr(DIRECCION);
if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) ==
-1 ){
if((err = errno) != EINPROGRESS){
fprintf(stderr, "Error de conexin del socket %d\n", errno);
exit(-1);
}
}

Ejemplo: eco con hilos cliente(2/2)


//Dejamos que el cliente enve y reciba datos
memset(buffer, '\0', TAMBUFER);
printf("Tecle algn texto a enviar (presione <enter>)\n");
fgets(buffer, TAMBUFER, stdin);
buffer[strlen(buffer)-1]='\0';
if( (bytecount=send(hsock, buffer, strlen(buffer),0))== -1){
fprintf(stderr, "Error enviando datos %d\n", errno);
close(hsock);
exit(-1);
}
printf("Envio de %d bytes\n", bytecount);
if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error recibiendo datos %d\n", errno);
close(hsock);
exit(-1);
}
printf("Bytes recibidos %d\n Cadena recibida \"%s\"\n", bytecount, buffer);
close(hsock);
}

Ejercicio
Desarrolle un cliente que pueda
trabajar con el siguiente servidor:

servidorsockethilos.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<pthread.h>
<unistd.h>
<errno.h>
<string.h>
<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<arpa/inet.h>
<sys/wait.h>
<signal.h>

int main() {
int ss,s1,s2,n;
fd_set sockfds;
struct timeval tv;
struct sockaddr_in my_addr;
struct sockaddr_in socks[PROCESOS];
pthread_t thread[PROCESOS];
int i=1;
ss = socket( PF_INET, SOCK_STREAM, 0 );
my_addr.sin_family = AF_INET; // Familia de protocolos
my_addr.sin_port = htons(PUERTO); // Nmero de puerto
memset( &(my_addr.sin_zero), '\0', 8 ); // Limpia la memoria

#define PUERTO 12345


#define PROCESOS 10
#define TAMBUFER 1024

//Abrimos el puerto a varios usuarios


setsockopt( ss, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int) );
//Preparamos el socket para trabajar
bind( ss, (struct sockaddr* )&my_addr, sizeof( struct sockaddr ) );
listen( ss, PROCESOS);

void *talker( void *d ) {


int i = 0;
char buf[TAMBUFER];
int fd;

n = sizeof( struct sockaddr_in );


i=0;
printf("Servidor corriendo ...\n");
while( 1 ) {
s1 = accept( ss, (struct sockaddr *)&socks[1], &n );
printf("Conexin de un cliente...\n");
pthread_create( &(thread[i++]), NULL, talker, (void *)s1 );
}

fd = (int)d;
while( 1 ) {
sprintf( buf, "%d\n", i++ );
write( fd, buf, strlen( buf )
+1 );
sleep(4);
}
}

return(0);
}

Ejemplo: eco con hilos servidor java


import java.io.*;
import java.net.*;

public class SEcoHilos {


public static void main(String[] args){
try{
ServerSocket s = new ServerSocket(9000);
System.out.println("Servidor listo en el
puerto"+
s.getLocalPort());
for(;;){
Socket cl = s.accept();
System.out.println("Cliente
conectado..\n");
Manejador m = new Manejador(cl);
m.start();
}//for
}catch(Exception e){
e.printStackTrace();
}//catch
}//main
}

class Manejador extends Thread{


Socket cl;
public Manejador(Socket cl){
this.cl = cl;
}//constructor
public void run(){
try{
PrintWriter pw = new PrintWriter(new
OutputStreamWriter(cl.getOutputStream()));
BufferedReader br = new BufferedReader(new
InputStreamReader(cl.getInputStream()));
String linea="";
for(;;){
linea= br.readLine();
System.out.println("Recibiendo mensaje: "+linea);
if(linea.indexOf("SALIR")>=0){
System.out.println("Cliente se va...");
cl.close();
break;
}
pw.println(linea);
pw.flush();
}//for
}catch(IOException io){
io.printStackTrace();
}//catch
}//run
}

Ejemplo: eco con hilos cliente java


import java.net.*;
import java.io.*;
public class CEcoHilos {
public static void main(String[] args){
try{
InetAddress srv = InetAddress.getByName("127.0.0.1");
Socket cl = new Socket(srv,9000);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(cl.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(cl.getInputStream()));
BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));
String linea="";
System.out.println("Escribe mensajes <ENTER> para enviar, <SALIR> para terminar\n");
for(;;){
linea= br2.readLine();
pw.println(linea);
pw.flush();
if(linea.indexOf("SALIR")>=0){
System.out.println("Adios...");
cl.close();
System.exit(0);
}//if
String eco=br.readLine();
System.out.println("ECO: "+eco);
}//for
}catch(Exception e){
e.printStackTrace();
}//catch
}//main
}

Prctica 5

SERVIDOR HTTP

Comunicacin

Solicitud HTTP
Lnea de solicitud, especifica el tipo de documento
solicitado. Formado por:
Mtodo (GET, POST, HEAD, etc)
Direccin URL
Versin (HTTP/1.0)

Campos del encabezado de solicitud, conjunto de


lneas opcionales que aportan informacin adicional
El cuerpo de la solicitud, lneas opcionales
separadas de las anteriores por una lnea en blanco
que permiten enviar datos. Por ejemplo en el
mtodo POST para llenar un formulario

Ejemplo
MTODO VERSIN URL<crlf>
ENCABEZADO: Valor<crlf>
. . . ENCABEZADO: Valor<crlf>
Lnea en blanco <crlf>
CUERPO DE LA SOLICITUD

GET http://es.kioskea.net HTTP/1.0


Accept : Text/html If-Modified-Since : Saturday, 15-January2000 14:37:11 GMT User-Agent : Mozilla/4.0 (compatible; MSIE
5.0; Windows 95)

Respuesta HTTP
Es un conjunto de lineas que se
envian desde el servidor al
navegador, las cuales son:
Linea de estado, especifica versin, el
estado de la solicitud echa y un texto
explicativo
Campos de respuesta, campos
opcionales que permiten aportar
informacin extra sobre la respuesta o el
servidor
Cuerpo de la respuesta, el cual contiene

Ejemplo
VERSIN-HTTP CDIGO EXPLICACIN <crlf>
ENCABEZADO: Valor<crlf>
. . . ENCABEZADO: Valor<crlf>
Lnea en blanco <crlf>
CUERPO DE LA RESPUESTA

HTTP/1.0 200 OK Date: Sat, 15 Jan 2000 14:37:12


GMT Server : Microsoft-IIS/2.0 Content-Type :
text/HTML Content-Length : 1245 Last-Modified : Fri,
14 Jan 2000 08:25:13 GMT

Desarrollo
Se implementar un servidor HTTP que
sea capaz de reconocer y servir
peticiones de recursos mediante los
mtodos GET, POST, HEAD (Ver RFC
2616)

You might also like