Thursday, November 24, 2011

Third Practical Presentation.





Code used to implement a simple client-server communication.

client code
#! usr/bin/python
import socket

print "teclear-- -----para"
print "sum n -> suma los primeros n enteros"
print "prim n -> muestra los primeros n numeros primos"

host = 'localhost'
port = 50000
size = 1024
seguir = 1
while (seguir == 1):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host,port))
    peticion = raw_input("tarea a realizar ")
    tarea = peticion.split()
    print tarea
    s.send(peticion)

    data = s.recv(size)
    #esperamos por todos los datos posible
    cadena = data
    while(data != 'EOF'):
        cadena = cadena+data
        s.send('ack')
        data = s.recv(size)

    if tarea[0] == 'prim':
        print "primeros %d " %int(tarea[1]),
        print "numeros primos"
                    
        primos = cadena.split()#convertir la cadena en lista
        contador = 0
        for primo in primos:
            print str(primo), 
            if contador > 9:
                print "\n"
                contador = 0
            contador += 1
        print "\n"

    elif tarea[0] == 'sum':
        print "suma de los  %d " %int(tarea[1]),
        print "primeros numeros enteros"
        print cadena
        
    s.close()
    salir = raw_input("terminar sesion (y/n):")
    if salir == 'y':
        seguir = 0
 

Server Code
#! usr/bin/python

import socket
from math import ceil
from math import sqrt
from sys import getsizeof


def primos(cuantos):
    if cuantos == 1:
        lista_primos = ["1"]
        
    elif cuantos == 2:
        lista_primos = ["1", "2"]
        
    else:
        faltan = cuantos - 2
        esprimo = 3
        lista_primos = ["1","2"]
        while(faltan>0):
            np = primo(esprimo)
            if np == 1:
                lista_primos.append(str(esprimo))
                faltan -= 1
            esprimo += 1
            print lista_primos    
    return " ".join(lista_primos)

def primo(posible_primo):
    primo = 1
    if (posible_primo % 2) == 0:
        primo =  0
    else:
        max_divisor = int(ceil(sqrt(posible_primo)))
        for i in range(3, max_divisor + 1):
            if (posible_primo % i) == 0:
                primo = 0
                break
    return primo


def sumaN(n):
    suma = (n*(n+1))/2
    return str(suma)

    

host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)

while 1:
    client, address = s.accept()
    peticion = client.recv(size)
    data = peticion.split()
    print "recibimos " +str(data)
    if data[0] == 'prim':
        numero = int(data[1]) #cuantos quieren
        resultado = primos(numero)
    elif data[0] == 'sum':
        numero = int(data[1])#cuantos
        resultado = sumaN(numero)
        
    #no cabe en un solo paquete
    if getsizeof(resultado) > size:
        contador = 0
        while(contador + size < getsizeof(resultado)):
            por_enviar = resultado[contador:contador+size]
            client.send(por_enviar)#enviar lo obtenido
            client.recv(size)#esperamos contestacion
            contador+=size
        if contador < getsizeof(resultado):#no se enviaron todos los datos
            client.send(resultado[contador:])#enviar lo que resta
            client.recv(size)#esperamos contestacion
        client.send("EOF")#cerramos la conexion 

    else:#cabe en un solo paquete       
        client.send(resultado)#enviar lo obtenido
        client.recv(size)
        client.send("EOF") #terminamos la transmicion
    client.close()
 
Next, an explanation of some parts of the code used to implement the client-server program showed in the presentation.


Client code
import socket

host = 'localhost'
port = 50000
size = 1024
 

Indicate the host and port of the machine we want to communicate with and the maximum size of bytes we can send to the other machine with the send() function.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
 
Create a socket an open a connection with a host and port numbers.

peticion = raw_input("tarea a realizar ")
tarea = peticion.split()
print tarea
s.send(peticion)
 
Ask for a request and send it to server.


data = s.recv(size)
#esperamos por todos los datos posible
cadena = data
while(data != 'EOF'):
    cadena = cadena+data
    s.send('ack')
    data = s.recv(size)
 
In case the server sends more data than the one function send() can handle, we wait until all data has been sent.

if tarea[0] == 'prim':
       .....
       .....
    elif tarea[0] == 'sum':
        .....
        .....
    s.close()
    salir = raw_input("terminar sesion (y/n):")
    if salir == 'y':
        seguir = 0
 
Checks what kind of request we made to the server and prints the data sent from the server in the correct format.Also ask for leaving or not the session, if we keep in the session it opens a socket connection because the actual socket connection is closed before asking for leaving or not the session.

Server code
client, address = s.accept()
peticion = client.recv(size)
data = peticion.split()
print "recibimos " +str(data)
if data[0] == 'prim':
     numero = int(data[1]) #cuantos quieren
     resultado = primos(numero)
elif data[0] == 'sum':
     numero = int(data[1])#cuantos
     resultado = sumaN(numero)
 
Accepts connections and checks the clients requests, those requests call the primos and sumaN functions.

if getsizeof(resultado) > size:
    contador = 0
    while(contador + size < getsizeof(resultado)):
        por_enviar = resultado[contador:contador+size]
        client.send(por_enviar)#enviar lo obtenido
        client.recv(size)#esperamos contestacion
        contador+=size
    if contador < getsizeof(resultado):#no se enviaron todos los datos
        client.send(resultado[contador:])#enviar lo que resta
        client.recv(size)#esperamos contestacion
    client.send("EOF")#cerramos la conexion 

else:#cabe en un solo paquete       
    client.send(resultado)#enviar lo obtenido
    client.recv(size)
    client.send("EOF") #terminamos la transmicion
client.close()

 
Once we call the functions that compute the clients requests, make sure that all the data can be sent no matter if exceeds the limit size of the send() function and close the connection.

The functions are defined as usual in any python code. As you can see this example works for just one client-server connection at a time, later implementations using threads can avoid this limitation.

Based in the code examples from:
http://ilab.cs.byu.edu/python/

1 comment:

  1. Confirmo aquí los 6+2 otorgados el día de la presentación.

    ReplyDelete