[#] Implementacja klient-serwer z wykorzystaniem SOCKET-ów w języku python

( Ostatnio zmieniony ndz., 19/04/2009 - 14:48 )
 

Prosty przykład, w jaki sposób można wykonać aplikację klient-serwer z użyciem języka skryptowego Python. Na stronie: Sockets in Python , dowiesz się więcej na temat implementacji wątków do obsługi gniazd.

serwer.py

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys, socket, thread

HOST = '10.1.1.100'
PORT = 11568
BUFSIZ = 1024
MAX_CONNECTION = 1
count = 0

def opisz_problem(msg):
  # definicja słownika
  e = {
    13:'Odmowa dostępu',
    'timed out':'Upłynął limit czasu',
    99:'Nie można zająć portu na tym adresie IP'
  }
  if e.has_key(msg[0]):
    return e[msg[0]]
  else:
    return msg



def handler(clientsock,addr):
  global count

  if count < MAX_CONNECTION:

    count += 1
    while 1:
      data = clientsock.recv(BUFSIZ)
      if not data: break
      print 'Odebrano dane od klienta', addr, ':', data

      # Potwierdzamy że otrzymaliśmy dane
      clientsock.send('Potwierdzam odebranie danych od: ' + str(addr[0]))

    # kończymy ten wątek i zmniejszamy licznik wątków
    count -= 1

  else:
    print 'zbyt wiele połączeń'
    clientsock.send('Zbyt wiele połączeń. Spróbuj ponownie później')

  print 'Klient', addr, 'zakończył sesję !'
  clientsock.close()



def main():
  serversock = None
  for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
      serversock = socket.socket(af, socktype, proto)
      print 'Przygotowuję gniazdko sieciowe:'
      print '-------------------------------'
      # ponowne użycie tego socketa jeśli już jest bindowany
      serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      print '[ + ] Ustawiam opcje dla gniazdka sieciowego:'
    except socket.error, msg:
      print msg
      serversock = None
      continue
    try:
      serversock.bind(sa)
      print '\t[ + ] Port:', PORT, 'na insterfejsie', HOST, 'został opanowany !'
      print '\t[ + ] Zaczynam nasłuchiwanie (max. ', MAX_CONNECTION, ' połączeń jednoczesnych)'
      serversock.listen(MAX_CONNECTION)
    except socket.error, msg:
      print '[ - ] Nie udało się zawładnąć portem:', PORT, 'i nasłuchiwać na nim, powód:', opisz_problem(msg)
      serversock.close()
      serversock = None
      continue
    break


  if serversock is None:
    print 'Nie udało się otworzyć gniazdka sieciowego !'
    sys.exit(1)
  else:
    print 'Gniazdko sieciowe gotowe !'

  """ Jeśli wszystko przebiegło zgodnie z planem, zaczynamy nasze działania """

  print '\nCzekam na połączenia ...'
  print '------------------------'

  while 1:
    clientsock, addr = serversock.accept()
    print 'Połączono z adresu:', addr[0]
    print 'Połączono z portu:', addr[1]
    thread.start_new_thread(handler, (clientsock, addr))


  print 'Zamykam serwer nasłuchujący'
  serversock.close()



if __name__ == '__main__':
  sys.exit(main())

klient.py

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import socket, sys

HOST = '10.1.1.100'
PORT = 11568
BUFSIZ = 1024
TMOUT = 1


def opisz_problem(msg):
  # definicja słownika
  e = {
    111:'Połączenie zostało odrzucone !',
    32:'Uszkodzone gniazdko sieciowe !',
    104:'Połączenie zresetowane przez serwer',
    'timed out':'Upłynął limit czasu !'
  }
  if e.has_key(msg[0]):
    return e[msg[0]]
  else:
    return msg


def main():
  tcpCliSock = None
  for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
      tcpCliSock = socket.socket(af, socktype, proto)
      print 'Przygotowuję gniazdko sieciowe:'
      print '-------------------------------'
      tcpCliSock.settimeout(TMOUT)
      print '[ + ] Ustawiam opcje dla gniazdka sieciowego:'
    except socket.error, msg:
      print msg
      tcpCliSock = None

    try:
      tcpCliSock.connect(sa)
      print '[ + ] Połączono z:', HOST, 'do portu:', PORT
    except socket.error, msg:
      print '[ - ] Nie udało się ustanowić połączenia: ', opisz_problem(msg)
      tcpCliSock.close()
      tcpCliSock = None
      continue
    break

  if tcpCliSock is None:
    print 'Nie udało się otworzyć gniazdka sieciowego !'
    sys.exit(1)
  else:
    print 'Gniazdko sieciowe gotowe !'


  """ Jeśli wszystko przebiegło zgodnie z planem, zaczynamy nasze działania """

  while 1:
    data = raw_input('Wprowadź dane do wysłania: ')
    try:
      tcpCliSock.send(data)
      print 'Dane wysłane do serwera:', data
    except socket.error, msg:
      print 'Otrzymano komunikat błędu:', opisz_problem(msg)
      powod = opisz_problem(msg)
      break

    # Pobieramy odpowiedź serwera
    try:
      data = tcpCliSock.recv(1024)
      if data:
        print 'Serwer odpowiedział:', data
      else:
        print 'Serwer nie odpowiedział'
    except socket.timeout, msg:
      print 'Otrzymano komunikat błędu:', opisz_problem(msg)

  print 'Zamykam połączenie z serwerem. Powodem było:', powod
  tcpCliSock.close()

if __name__ == '__main__':
  sys.exit(main())
5
Twoja ocena: Brak Średnio: 5 (3 głosy)