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()