Sei sulla pagina 1di 9

12

Individualmente- roscados,
concurren! Servidores (TCP)

12.1 Lntroducción
El capítulo anterior Ilus. Cómo concurrenc trates más. Orientado a la conexión de
servidores funcionan. Ellos usan el sistema operatlng faclhties
para crear un subproceso para.te separa cada con- nection y a1bajo el sistema
operativo para el procesador timesHce entre los subprocesos. Este capítulo il1ustraces un
diseño ídea thal es interesti ng, pero no obv]ou: muestra cómo un servidor puede ofrecer a los
clientes la simultaneidad aparente. utilizando un solo hilo. En primer lugar, ex.amínes
la idea general. 1t :explica por qué este enfoque es factible y cuando no puede ser superior
a una aplicación usando multíple procesos o subprocesos. Segundo, ü considera cómo una
individualmente subprocesos.S erver utiliza el sistema Windows a handlc funcfüms
multíple connectitms concunencly. El ex.amplio server sigue AJgorilhm 8.5T.

12.2 Procesamiento de datos el Dr. iven en un servidor.


Para 1/0 domiaates applícations donde el costo de la preparación de
una respuesta a una solicitud, un servidor puede utilizar UO asincrónica para prov
ide concurrenc aparente y entre c1ients. Thc idea ís simple: disponer de un único subproceso
servidor para mantener las conexiones TCP abiertas a mu J - tiple cJicnts.. y tienen lhe lado
servidor]c una conexión determinada cuando llegan datos. Por lo
tanto. El servidor utiliza la llegada de datos de ignición 10.slng proces.
Para entender por qué el enfoque worksj considerar el eco concurrentes servcr
descrito en el capítulo anterior del Che. Para lograr la ejecución simultánea, el servidor crea
un flujo esclavo para manejar cada nuevo conneclion. En teoría, el s.erver depcnds
sobre

TSee página 1 de 14!ic Algoríthm ription de 8.5.


144 Si.ngly-Thn!ida::d, Cune n.t Llrre !servidores TCP) Cap. 12

La actúan por cortes de tiempo del sistema mecanismo para compartir la CPU
entre los tlrreads. y hcnce. Entre las conexiones.
Ln pract ice sin embargo, un servidor de eco seJdom depende DO
L tímeslícing. Si uno pudieron presenciar la ejecución de un servidor de eco concurrente de
cerca. Uno wou ld encontrar thal la llegada de datos a menudo controla el procesamiento. El rea
de re]ates en el flujo de datos a través de internet. Los datos llegan a[ el servidor jn
burst.s, no en una corriente constante porque el under- J ying diserete intemet
entrega los datos en paquetes. Los clientes agregar al comportamiento a ráfagas
si deciden enviar a b-cerraduras de datos para la thac resultin,g segmentos TCP cada monte
ínto un único datagrama IP. Che ca server, cada esclavo subproceso pasa la mayor parte de l ts
tiempo bloqueado en una cal1 a recv esperando la próxima ráfaga para llegar. Una vez
que lleguen los datos. El recv caJ J re& tums y el flujo esclavo ejecuta. El esclavo pide
sern:J para enviar los datos a lhe dien1 y la n llamadas recv para esperar más datos_ una
CPU que puede manejar el ]oad de muchos clíents wíthout ralentizando debe ejecutar lo
suficientemente rápido para completar el cy de receí v•ng y s.termina antes de que
los datos llegan a otro esclavo.
Por supuesto, si la cocina local se vuelve tan grande que la CPU no puede procesar
una solicitud antes de que llega otra. Lleva más tiempo compartido. El sistema operativo
cambia el pro- cessor entre ali esclavos tliat guardar datos para procesar. Para servicios
simples th.En req uire littlc processi ng para e.ach solicitud. Es muy probable que la
ejecución wm sea impulsada por la llegada de daca. A surnmarize:

Setvers tbat simultáneas requieren Jitr!


e procening tiempo por requert suelen comportarse de una manera
sequentia[ donde la llegada de desencadenadores de datos e.xecution.
Sólo TimeJharing toma el relevo si el foad se vuelve tan alta que la CPU
puede manejar ir .secuencialmente.

123 procesamiento controladas por datos con un único subproceso


Understamií ng la ce¡uential carácter de com:urrent servir.-·s comportamiento alJows
us co entender cómo un solo subproceso puede realizar la tarea de ame. Imagine un único
servidor TCP connecüons lhread que ha abierto a muchos clientes. El subproceso se bloquea
esperando datos 10 llegan. Tan pronto como llegan datos
sobre cualquier conexión, el subproceso despierta. mano les. El REQ uest. y envía una
respuesta. Lt lhen bloques de nuevo. esperando más datos w llegan desde nectlon anotller
contras. Mientras lhe CPU es lo suficientemente rápido como para satisfacer la carga
present- ro ed al servidor, el único vers lhread•en empuñaduras req ues[s así como una
versión con multíple lhreads. De hecho, ser.causa una slngl}·-[hreaded ímpJementation
requiere menos witchlng entre contextos de rosca, puede ser capaz de manejar una carga
mayor que slíghtly una aplicación que utiliza varios subprocesos.
La clave para una programación síngly-lhreaded, servidor simultáneo Hes asincrónica
en el uso de la Organización mediante la selección de funciones de Windows
Sockets. Un servidor crea
un socket para ea.ch de las conexiones ít debe gestionar llamadas y, a
continuación, seleccione [O lamentación para datos para llegar a una de ellas)·. De hecho,
se puede esperar seiect becau para E/S en todos los posibles sock ets, también puede esperar
nuevas conexiones tbe al mismo tiempo. M Algorith de- taíJed 8.5 enumera los pasos que
un subproceso síngly seiver utiliza.
Sec_ L2_4 Rosca de Singly-Thr Srrocture d Server 145

12..4 Thread Estructura de A. Individualmente-Servidor roscada


Figura 12.1 illustrares la rosca y la estructura de un socket individual-aded, con-
Actual.S erver. Qne. Lflread gestiona todas las tomas. '

Server
..,... Appiication
Rosca

Toma para la Para conexiones Jndlvidual socketFuncionamiento


APNU connectlon .'Ais1em

Figura 12.l La estructura de un conneclion lhread-oriemed.S


erver lhac logra com;:urreru;:y con un único subproceso.
El subproceso gestionar múltiples sockets-

En esencia, un cantar]e hilo musl servidor realice los deberes tanto de los subprocesos
de maestro y esclavo. Lt maímains un conjunto de tomas.. wílh uno socke[ en el
conjunto dependiente del bien krwwn puerto en
el que el maestro aceptaría connectíons. El otro zócalo s ín lh.e
establece ea.ch corresponden a una conexión a través de un sfave whkh wou]d atender las
peticiones. El
Server me pasa juego de socke[ descriprors como argumem ·a seiect y lamentos para activi-
Ty sobre ninguno de ellos. Cuando select devuelve. Ít pasa por detrás de una máscara que
spedfies whkh bil de la desctjptors en el juego esté listo. El servidor utiliza el orden en el
que los descriptores be- vienen preparados para decidir cómo proceder.
Para distinguir entre maestro y esclavo operaciones. a solas-threaded server utiliza el
descriptor. Si el descriptor que corresponde al maestro dle socket está listo, el servidor
realiza la misma operación el maestro wou ld perfonn: llama accepl en el socket para
obtener una nueva conexión. Lf un descriptor thal corresponde a un sla\le
zócalo .- viene listo. El servidor realiza la operación un esclavo perfonn: lt
caUs recv para obtener una solicitud. y luego respuestas i t.
146 Singly-Thtt.adcd. Sc:rvus Concumnl (TCP)

12.5 Un ejemplo Singly-Threaded Servar _ECO


Un eJ:amplio ayudará a aclarar las ideas y ex.plain cómo un subproceso con-
síngly. c:urrent servidor funciona. Examinar archivo TCPmechd.cpp. Thc contaios
wbich código para un subproceso solos :iCI'Ver que implementa el servicio ECHO.

/ • TCPmechd. cpp - JM.in, echo •¡

<tinclude Winsock
linclude .h>
<string.h>.

#Define QLEN 5 / * Máx.:mínimo co.nnection lengt cola:h "'!

Tdefine EllFSIZE 4096 (2 , 0)


F definir \'6V
ERS

Void Errexit (const char •, • •


• } ; scx:::KB"r Pasari
Const char * P ! Int
' ; int Echo {scx:Ke'i') ;

/*------------------------------------------------------------------
* Principal concurrente - 1'CP server f o :rorJ service
·--------------------------------------------------------------------
*/
Void
Principales 1 i n t .rqc, char *'argv[ ] }
{
Char s •Servicio = / * Nombre de servicio o el número de puerto
tru.ct "echo· ; sockaddr_i */
SOCKBT n msock fsin;; /* El fran dirección de un cliente */
Ñl_se
Rfds; /* Socket del servidor maestro "'/
t / * Leer el conjunto de descriptores F
Fd_aet
afds;
ile J
/* Archivo activo descripto set 1
Mt Alen: Servicio = argv [l]:
WSADATA wsdata ; Me salto
Uns:firmado int Fdndx;

Interruptor (argc ) {
Caso L!
Br-eak;
Caso 2:
I* f ran- longitud de dirección

""" /
Sec. 12. An Examp]e Sj:agly-Thrcaded ECHO S!!:rnr 147
5

Valor predeterminado:
T { errexi•uso : Tl:Prnechod rpuerto] \n 11 )

(WSVE CWSAStartup i f&S , &wsda..ta) L=-= o )


Errerl.t ( •WSJIStart.up fai1ed\n• ) ;

msock = passive/l'C.P ( servicio; • QLENJ

FD_zERO{&af ds ) ;
FD_sE'l' (msock, &afds ) ;

Mientras que (1){


Memcpy (&rfds, &afds; aizeof (rfds)

If ( Seleccionar ( FD_sETSI ZE, &ds de rf. ( Fd_set *) O , ( :fd_ett * ) O .


{Estruc:t timeval "* O } } == '_ERROR SCCKB1}
Errexi.t {•Seleccionar error = %d\n",
GetLastError( ) ) ; (f'D_ISSET(msock, &Rf ds) ) {
.9LCKB"r Ssoc::k;

A.len "" sizeof ( f pecado} ;


Ssock = Aceptar (msock, {Struct sockaddr •)& f pecado,
&A.len) ;
If (Ssock ======= mvALID_sr:xur )
Errexit ( •Aceptar. : .Un error.\n ,
Get.Last.Brror C l ) ;
P!_l sHI'(ssoek. &Afds) ;
}

Para FDN (.d:x=O. Fdndx<rfds.f d._count : ++fdndx) {


SCCICE f d'I' = rfda.fd_array (fdndx];

Si (F D = msocit && FD_ISSET ( fd, &rfds) )


Si (ecbo(fd);::: 0} {
( Id) closesoclc.et ( fd) ;
FD_CLR.( fd, W.FDS) :
}
}
}
)
?48 Solos -roscados, Concurrcnt servidores (TCP) O.ap. 12

/*-----------------------------------------------------------------------
* Echo: echo un búfer de datos, returni.ng BYTE COUNT
·----------------------------------------------------------------------
*/
Int
Echo ( soc:xE'l'" f d}
{
Char Buf[EUFSIZE];
Int Ce:

Ce = recv (fd. Buf , sizeof buf , 0).


If {Ce == SOCKET_ERROR}
Errexit ( ,.echo recv error %d\n " , GetLast.Error ( ) :
Si (ce && enviar{fd. buf. ce. 0} :SC:x::Ke'I'...,.ERROR}
{ Errexit 1techo enviar error %d\n a GetLastError{ ) } j ¡
Retmn ce;
}

El servidor singlythreaded comienza, como el servidor maestro en una aplicación


multiproceso, por open!ng un socket pasivo en el puerto conocido. Ll
utiliza FD_ZERO Y FD_SET para crear un vector que correspcmds descriptores a la toma i1
que desea probar. A continuación, el servidor. entra en un bucle que infin i n wh
ich llama selecl esperar uno o más de los descripcors esté listo_
Lf el descriptor principal pasa a estar preparado. El servidor llama a aceptar para obtener
una nueva con- nectíon. J[ agrega el descriptor para la nueva conexión para
el conjunto que administra. y contin- ues a waít de mure actividad. Si un s.!ave descripror
esté preparada, lhe server caUs pro- cedimiento eco que llama recv t-o obtener
datos froin la conexión y enviar para enviar i hasta el 1f dienL uno de los esclavos des.cri
ptors informa de un fin-de-fichero y condi üon. El servidor de dosis el descriptor y utiliza la
macro FD_CLR para quitar ít desde el conjunto de descriptores select utiliza.

12.6 Resumen
Ejecución en concurn::servidores nt a menudo es impulsada por la llegada de datos por
cortes de tiempo y no por el mecanismo del sistema operativo Linderlying. En los casos en
que el servicio requiere proceso lirde lhe;ing. Una individualmente subprocesos pueden
utilizar implementatíon UO asincrónica para administrar las conexiones
a múltiples clientes tan eficazmente como una implementación tha1
utiliza varios subprocesos o procesos.
El individual-threaded ímplementaüon desempeña las funciones de maestro
y esclavo _ \Vhen subprocesos el patrón sock.el be.comes listo. El seiver acepta una
conexión nueva. Cuando cualquier otro socket está listo, el servidor re ves una petición
y envía una respuesta. Un servidor de subprocesos exarnple
individualmente para el servicio ECHO iUustrates t.h'e ideas y muestra los detalles
programrning.
Fot" fiurther Smdy 149

Para un estudio más profundo

Un buen protocolo no speclfication nm limitando la aplicación. Por ejemplo, lhe


individualmente.lhreaded server descrita en este capítulo implemencs lhe prococol
eco de una multa por parte de la Poste) [RFC 862]. El capítulo 11 muestra un ejemplo de un
servidor multiproceso, con- actual construido a partir de la misma especificación del
protocolo.

EXERCISES

12.1 Realizar una prueba que eperiment lhe Ejemplo ECHO servidor puede manejar conexiones
Concurrenl..ly.
12.2 ¿ Tiene sentido utilizar el 10 lhis jmplementation discutidas en el capítulo de 1 día·
TI.ME servhielo? Por qué o why ni';'
12.3.d lbe Wíndows Rea docu mentales para averiguar 1él represeruation o.f exacta descripción e n la
lista pasan a seiec1. Wríle llle FD_SET y FD_Cl.R macros.
12.4 comparar la perfonnance de singl y-th leída y multílhreaded >erver imp lemen lat iom en un i:::ompurer con
mu lliple processon. En wha.t circumsf ances será un singly- thre-.aded ven;ión bener
perfonn que (o igual) a una versión ultithreaded m?
LLJ Lacge Suppoe un número de clientes (p.ej. 100) ; el servidor exampJe acceso en este capítulo al.
Al mismo tiempo. Exp)ain whal cada cJienc míght observar.
12..6 puede un servidor multiproceso solos nunca privar a un cliente de servicio mientras repealedly
honores solicitud:s desde otra'? Puede multiproceso ehibit implemenrntion nunca la
misma behaví o? Explai n.

Potrebbero piacerti anche