Reactie plaatsen 
 
Waardering:
  • 0 stemmen - gemiddelde waardering is 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sockets
Auteur Bericht
Elco Offline
Ep2 Volunteer
****

Berichten: 1.237
Lid sinds: 04-2006
Reputatie: 29
Bericht: #1
Sockets
Omdat het net even makkelijker leest in het Nederlands heb ik even snel deze beginner-tutorial samengesteld voor het gebruik van (single-threaded server en TCP only) sockets in Python :)

TCP-ECHOCLIENT IN PYTHON

Het gebruik van sockets in Python wordt ondersteunt via de socket module. Een typisch voorbeeld bij socket-tutorials is het maken van een echo-server. In dit artikel zullen we zo een dergelijke client-server toepassing bouwen. (We maken hier gebruik van TCP-sockets, indien er genoeg interesse is voor UDP-sockets kan ik daar ook een artikel over schrijven :))

Server-gedeelte:
Zoals reeds vermeld moet gebruik gemaakt worden van de socket module van Python, deze kan geimporteerd worden met volgende code:
Code:
from socket import *
Om een socket aan te maken moeten we 2 zaken opgegeven: de host en het poortnummer. Om kort te zijn kan op deze manier een proces worden geidentificeerd dat op een bepaalde host loopt. Deze 2 zullen we als een tuple voorstellen genaamd locatie (bevat respectievelijk host- en poortnr-informatie):
Code:
locatie=('localhost',12345)
We hebben nu dus de benodigde module opgegeven, en we hebben informatie over de locatie, nu moet dus nog de socket zelf aangemaakt worden. Dit gebeurt als volgt:
Code:
serversock = socket(AF_INET, SOCK_STREAM)
Hierin geeft SOCK_STREAM aan dat het TCP-sockets betreft, en AF_INET dat het voor internet protocol (IP) bedoeld is. (We maken dus TCP-IP gerichte sockets)

We hebben nu een socket aangemaakt, maar deze is nog 'maagdelijk', het is enkel een object, maar het doet nog niets. Voor een serversocket te bekomen moeten we het binden aan een het opgegeven adres, en dan geven we de socket informatie over de aanvragen op de locatie die we hem doorgaven:
Code:
serversock.bind(locatie)
serversock.listen(2)
Bij listen kunnen we een parameter opgeven (>=1) die aangeeft hoeveel clients zullen kunnen verbonden worden (deze worden in een wachtrij geplaatst indien de server al een client bedient) Indien de wachtrij vol is worden bijkomende verbindingen geweigerd. (Om ipv sequentiele toegangen toe te staan kan ook gebruik gemaakt worden van een threaded server, indien ook hier vraag naar is, schrijf ik daar ook een deel over :))

Nu kunnen we de 'functionaliteit' van de server gaan implementeren. Voor de eenvoud zorgen we dat de server oneindig blijft functioneren, dus met een oneindige lus (while 1)
PHP-code:
while 1:
   print 
'Wachtend op verbinding'
   
clientsockadres serversock.accept()
   print 
'Connectie van: 'adres


serversock
.close() 
Door accept() op te roepen zal het serverprogramma wachten tot er een verbinding wordt gemaakt met onze ingestelde socket. Dan pas gaat hij verder met de uitvoering van de volgende print. Accept() geeft dan een socket-object terug dat een voorstelling is van de socket van de client (clientsock). We kunnen dit gaan gebruiken om de data uit te lezen of te schrijven. Verdere info over de locatie van de client krijgen we in variabele adres. De verbinding wordt gesloten met serversock.close()

Nu kan dus verbinding gemaakt worden met de server, maar deze doet nog niets zinnigs: een echo-server zal info inlezen en diezelfde info opnieuw versturen. Dit doen we opnieuw in een lusje:
PHP-code:
while 1:
        
data clientsock.recv(1024)
        if 
data:
            
clientsock.send('echo:' data)
        else:
            break
    
clientsock.close() 
Als we dit nu allemaal samenvoegen krijgen we het volgende programma:
PHP-code:
from socket import *

locatie=('localhost',12345)
serversock socket(AF_INETSOCK_STREAM)

serversock.bind(locatie)
serversock.listen(2)

while 
1:
    print 
'Wachtend op verbinding'
    
clientsockadres serversock.accept()
    print 
'Connectie van: 'adres

    
while 1:
        
data clientsock.recv(1024)
        if 
data:
            
clientsock.send('echo:' data)
        else:
            break
    
clientsock.close()

serversock.close() 
Met behulp van de recv(1024) lezen we een buffer van 1024 bytes in vanuit de socket, zolang die niet null is sturen we de string bestaande uit deze buffer en 'echo:' ervoor terug naar de client via send() van de socket.

Client-gedeelte:
Het maken van de client-socket verloopt vrij gelijkaardig. Maar hier moeten we gebruik maken van de connect methode van de socket, en opgeven met welke locatie we verbinding willen maken:
Code:
from socket import *

locatie = ('localhost', 12345)
clientsock = socket(AF_INET, SOCK_STREAM)
clientsock.connect(locatie)
Nu zullen we ter illustratie een string opsturen en kijken wat we terugkrijgen van de server (hopelijk hetzelfde als wat we opgestuurd hebben, met 'echo:' ervoor) :):
Code:
data = 'TESTING SERVER'
clientsock.send(data)

data = clientsock.recv(1024)
print data

clientsock.close()
Het totale client programma ziet er dan als volgt uit:
PHP-code:
from socket import *

locatie = ('localhost'12345)
clientsock socket(AF_INETSOCK_STREAM)
clientsock.connect(locatie)

data 'TESTING SERVER'
clientsock.send(data)

data clientsock.recv(1024)
print 
data

clientsock
.close() 
Bij eventuele fouten (typ-fouten zijn snel gemaakt, maar de 'volledige code blokken' zijn rechtstreeks gekopieerd uit werkende codebestanden dus die werken zeker), vragen of opmerkingen laat gerust iets weten :)

Grtz,
Elco


EDIT:
even de code bestanden voor server en client bijgevoegd in zip als bijlage (al bedankt voor de goede respons ;))


Bijlagen
.zip  echoserver_python_code.zip (Grootte: 624 bytes / Aantal keer gedownload: 6)
30-04-2006 23:35:39
De website van deze gebruiker bezoeken Alle berichten van deze gebruiker zoeken Reageren op dit bericht
Jasper Online
Ep2 Admin
******

Berichten: 15.056
Lid sinds: 04-2006
Reputatie: 223
Bericht: #2
RE: Sockets
Vet ernstig, hier heeft gewoon nooit iemand op gereageerd?!

Om de zeven minuten denkt de vrouw dat de man alleen maar aan seks denkt.
15-02-2007 11:59:15
De website van deze gebruiker bezoeken Alle berichten van deze gebruiker zoeken Reageren op dit bericht
Thijs Offline
Linux Fan !
**

Berichten: 40
Lid sinds: 03-2007
Reputatie: 0
Bericht: #3
RE: Sockets
hallo, me gemist ? :D goede tut !
07-08-2007 09:12:00
Alle berichten van deze gebruiker zoeken Reageren op dit bericht
Jasper Online
Ep2 Admin
******

Berichten: 15.056
Lid sinds: 04-2006
Reputatie: 223
Bericht: #4
RE: Sockets
Thijs schreef:goede tut !
Na anderhalf jaar heeft Elco dan tóch z'n erkenning :D :D

Om de zeven minuten denkt de vrouw dat de man alleen maar aan seks denkt.
07-08-2007 16:18:46
De website van deze gebruiker bezoeken Alle berichten van deze gebruiker zoeken Reageren op dit bericht
Thijs Offline
Linux Fan !
**

Berichten: 40
Lid sinds: 03-2007
Reputatie: 0
Bericht: #5
RE: Sockets
Hoe maak mijn server telnet beschikbaar met telnetlib ?

PHP-code:
telnet localhost port 
09-08-2007 10:19:07
Alle berichten van deze gebruiker zoeken Reageren op dit bericht
Reactie plaatsen 


Ga naar locatie:


Contact opnemen | Ep2 | Naar boven | Naar inhoud | Archiefmodus | RSS-syndicatie