среда, 15 июня 2011 г.

Пример клиент TCP и UDP версий клиент-сервера на Python на сокетах.

Всем привет! Сегодня я покажу пример реализации простого клиент-сервера на Python.

Цель:
Реализовать службу Daytime (официальный номер порта 13), как ориентированную, так и не ориентированную на соединение.
Daytime-сервер, ориентированный на соединение прослушивает порт 13. Как только появляется запрос на соединение, сервер принимает запрос и тут же отсылает строку, содержащую информацию о текущем времени и дате. После этого сервер закрывает соединение (все пришедшие во время соединения данные от клиента игнорируются).
Daytime-сервер, не ориентированный на соединение ждет датаграмму на порту 13. Как только появляется сообщение (вся данные в сообщении игнорируются), сервер тут же отсылает строку, содержащую информацию о текущем времени и дате.
Примечание: Стандарт (RFC 867) не устанавливает спецификацию формата возвращаемой строки, но рекомендует чтобы она состояла из печатных ASCII-символов и заканчивалась комбинацией CrLf. Пример строки: “Tuesday, February 22, 1982 17:37:43-PST”.

Исходники:


Клиент сервер на TCP

TCP сервер http://dpaste.com/554737/ :


# -*- coding: utf-8 -*-
__author__ = "dehimer Novikov Denis Yurevich"
# connection-oriented server


import socket
import time 
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("localhost", 13))
server_socket.listen(5)

print "TCPServer Waiting for client on port 13"

while 1:
    client_socket, address = server_socket.accept()
    have_connect = 1    #if all clients are disconnected
    while have_connect:
        data = client_socket.recv(256)
        print len(data)
        print data
        if (data <> 'Q' and data <> 'q'):
            print "I got a connection from ", address
            data = ('On server now: ' + time.asctime(time.localtime())+ '\n')
            client_socket.send(data)
        else:
            client_socket.close()
            have_connect = 0
            break;



TCP клиент http://dpaste.com/554738/ :


# -*- coding: utf-8 -*-
__author__ = "dehimer Novikov Denis Yurevich"
# connection-oriented client

import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 13))

while 1:
    
    data = raw_input ( "SEND( TYPE q or Q to Quit):" )
    if (data <> 'Q' and data <> 'q'):
        client_socket.send(data)
        data = client_socket.recv(256)
        print data
    else:
        client_socket.send(data)
        client_socket.close()
        break;

UDP клиент-сервер

UDP сервер http://dpaste.com/554739/ :


# -*- coding: utf-8 -*-
__author__ = "dehimer Novikov Denis Yurevich"
# not a connection-oriented server

import socket
import time

server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("", 13))

print "UDPServer Waiting for client on port 13"

while 1:
 data, address = server_socket.recvfrom(256)   #receive data and sender's address
 data = ('On server now: ' + time.asctime(time.localtime())+ '\n')
 server_socket.sendto(data, address)
 print  "I got a connection from ( " ,address[0], " " , address[1] , " ) "

UDP клиент http://dpaste.com/554740/ :


# -*- coding: utf-8 -*-
__author__ = "dehimer Novikov Denis Yurevich"
# not a connection-oriented client

import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while 1:

 data = raw_input("Type something(q or Q to exit): ")
 if (data <> 'q' and data <> 'Q'):
  client_socket.sendto(data, ('127.0.0.1', 13))
  data = client_socket.recv(256)                 # receive up to 256 bytes
  print data
 else:
  break
client_socket.close()


Результат:

Ориентированный на соединение сервер/клиент:
сервер





клиент





Неориентированный на соединение сервер/клиент:
сервер



клиент






Ну вот собственно все=) Дальше покажу пример чата на сокетах, опять же в TCP и UDP версиях.
На вопросы обязательно отвечу в комментариях. Пишите.

воскресенье, 12 июня 2011 г.

Python. Парсер топиков с Хабра

Всем привет. На днях решил написать небольшой Python скрипт.
Собственно что делает: создает и запускает html страничку с ссылками в виде списка имен топиков.

Код ниже: http://dpaste.com/553390/


#-*- coding: utf-8 -*-
#author: Novikov Denis Yurevich den-vse@yandex.ru dehimer
# это надо будет вам скачать поставить, если не имеется
import lxml.html 
import urllib2

#откуда парсим
page = urllib2.urlopen('http://habrahabr.ru/')
doc = lxml.html.document_fromstring(page.read())

#открываем файл на запись
f = open('HabrNews.html', 'w')

#список новостей (просто строка оформленная в виде списка ссылок)
#заполняется в цикле ниже
news_list=''

#выдираем в цикле все ссылки с классом "topic"
#и добавляем к списку новостей
# (перевод в cp866 для вывода на консоль в винде - хотя это вообще не нужно)
for topic in doc.cssselect('h2.entry-title a.topic'):

    if topic.text:                
        s =  str(topic.text.encode('cp866', 'replace'))
        print s #покажем на консоль
        news_list += '<li><a href="'+topic.attrib['href']+'">'
        news_list += s.decode('cp866').encode('utf-8')+'</a></li>'
        

#тело html в который подставляем получившийся список топиков        
html_code = '''
            <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                </head>
            <body>
            <h2>Новости хабра</h2>
                <ul>%s</ul>
                
            </body>
            </html>
            ''' % news_list

#запишем и закроем (исключения ловить не будем, хотя не помешало бы)
f.write(html_code)        
f.close()

#а это чтобы по окончанию работы автоматически открылся наш html
import os
os.system('HabrNews.html')

пс: версия языка 2.7