python socket学习

1、简单实例:node

实现客户端向服务端发送的信息,服务器收到信息后加上当前时间再返回给客户端python

服务端实现:
服务器

#!/usr/bin/python
import socket, traceback, time
host = ''
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)
while 1:
    try:
        clientsock, clientaddr = s.accept()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()
        continue
    try:
        print "Got connection from", clientsock.getpeername()
        while 1:
            data = clientsock.recv(4096)
            if not len(data):
                break
            clientsock.sendall("[%s] %s" % (time.ctime(),data))
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        traceback.print_exc()
try:
    clientsock.close()
except KeyboardInterrupt:
    raise
except:
    traceback.print_exc()

客户端实现:网络

#!/usr/bin/pythonh
import socket, ssl
host = '192.168.209.128'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
        data = raw_input('please input data:')
        if not data:
                break
        s.sendall(data)
        data = s.recv(4096)
        print data
ssl_sock.close()

运行测试:
异步

[root@localhost example]# python echoclient1.pysocket

please input data:test pythonide

[Sun Sep 15 14:38:47 2013] test python测试

please input data:test 1111111111111111111111线程

[Sun Sep 15 14:38:52 2013] test 1111111111111111111111server

please input data:


2、socket 多任务处理

以上代码要实现的功能是实现了,可是当你用多个客户端同时执行向服务器端发送信息的时候,就发现同一时间服务端只能处理一个链接,其余的没法正常返回。这是由于服务端的单线程实现的,当收到一个客户端请求处理的时候,就会进入阻塞状态,没法同时处理多个任务。

为了可以同时为多个客户端服务,须要可以同时处理多个网络链接的方法。可经过三种方法来实现:

forking、threading和异步I/O。


经过threading实现服务端:

#!/usr/bin/python
import socket, traceback, os, sys, time
from threading import *
host = ''
port = 8000
def handlechild(clientsock):
        print "New child", currentThread().getName()
        print "Got connection from", clientsock.getpeername()
        while 1:
                data = clientsock.recv(4096)
                if not len(data):
                        break
                clientsock.sendall("[%s] %s" % (time.ctime(),data))
        clientsock.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind((host, port))
s.listen(1)
while 1:
        try:
                clientsock, clientaddr = s.accept()
        except KeyboardInterrupt:
                raise
        except:
                traceback.print_exc()
                continue
        t = Thread(target = handlechild, args = [clientsock])
        t.setDaemon(1)
        t.start()

这样就能够让服务器同时处理多个任务了。


3、在服务端和客户端使用ssl

首先建立一个自签名证书:

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.key


服务端:

#!/usr/bin/python
import socket, ssl, traceback, threading, sys, time
host = ''
port = 443
def Myhandlechild(clientsock):
        print "New child", threading.currentThread().getName()
        print "Got connection from", clientsock.getpeername()
        while 1:
                data = clientsock.recv(4096)
                if not len(data):
                        break
                clientsock.sendall("[%s] %s" % (time.ctime(),data))
        clientsock.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(5)
while 1:
        try:
                clientsock, clientaddr = s.accept()
                connsock = ssl.wrap_socket(clientsock, server_side=True,
                                           certfile="cert.pem", keyfile="cert.key")
        except KeyboardInterrupt:
                raise
        except:
                traceback.print_exc()
                continue
        t = threading.Thread(target = Myhandlechild, args = [connsock])
        t.setDaemon(1)
        t.start()


客户端:

#!/usr/bin/pythonh
import socket, ssl
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ssl_sock = ssl.wrap_socket(s,ca_certs="cert.pem", cert_reqs = ssl.CERT_REQUIRED)
ssl_sock.connect(('127.0.0.1', 443))
while 1:
        data = raw_input('input data:')
        if not data:
                break
        ssl_sock.sendall(data)
        data = ssl_sock.recv(4096)
        print data
ssl_sock.close()
相关文章
相关标签/搜索