c/s架構:客戶端/服務器架構python
C/S架構與socket的關係:shell
咱們學習socket就是爲了完成C/S架構的開發編程
爲什麼學習socket必定要先學習互聯網協議:設計模式
1.首先:本節課程的目標就是教會你如何基於socket編程,來開發一款本身的C/S架構軟件緩存
2.其次:C/S架構的軟件(軟件屬於應用層)是基於網絡進行通訊的服務器
3.而後:網絡的核心即一堆協議,協議即標準,你想開發一款基於網絡通訊的軟件,就必須遵循這些標準。網絡
4.最後:就讓咱們從這些標準開始研究,開啓咱們的socket編程之旅架構
socket層ssh
Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。socket
因此,咱們無需深刻理解tcp/udp協議,socket已經爲咱們封裝好了,咱們只須要遵循socket的規定去編程,寫出的程序天然就是遵循tcp/udp標準的。
套接字起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 Unix,即人們所說的 BSD Unix。 所以,有時人們也把套接字稱爲「伯克利套接字」或「BSD 套接字」。一開始,套接字被設計用在同 一臺主機上多個應用程序之間的通信。這也被稱進程間通信,或 IPC。套接字有兩種(或者稱爲有兩個種族),分別是基於文件型的和基於網絡型的。
基於文件類型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基於文件的套接字調用的就是底層的文件系統來取數據,兩個套接字進程運行在同一機器,能夠經過訪問同一個文件系統間接完成通訊
基於網絡類型的套接字家族
套接字家族的名字:AF_INET
(還有AF_INET6被用於ipv6,還有一些其餘的地址家族,不過,他們要麼是隻用於某個平臺,要麼就是已經被廢棄,或者是不多被使用,或者是根本沒有實現,全部地址家族中,AF_INET是使用最普遍的一個,python支持不少種地址家族,可是因爲咱們只關心網絡編程,因此大部分時候我麼只使用AF_INET)
服務端套接字函數
s.bind() 綁定(主機,端口號)到套接字
s.listen() 開始TCP監聽
s.accept() 被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來
客戶端套接字函數
s.connect() 主動初始化TCP服務器鏈接
s.connect_ex() connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常
公共用途的套接字函數
s.recv() 接收TCP數據
s.send() 發送TCP數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
s.sendall() 發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)
s.recvfrom() 接收UDP數據
s.sendto() 發送UDP數據
s.getpeername() 鏈接到當前套接字的遠端的地址
s.getsockname() 當前套接字的地址
s.getsockopt() 返回指定套接字的參數
s.setsockopt() 設置指定套接字的參數
s.close() 關閉套接字
面向鎖的套接字方法
s.setblocking() 設置套接字的阻塞與非阻塞模式
s.settimeout() 設置阻塞套接字操做的超時時間
s.gettimeout() 獲得阻塞套接字操做的超時時間
面向文件的套接字的函數
s.fileno() 套接字的文件描述符
s.makefile() 建立一個與該套接字相關的文件
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(('192.168.20.105',8080)) phone.listen(5) while 1: conn,addr=phone.accept() print('線路是%s' % conn) print('地址是',addr) while 1: try: cmd = conn.recv(1024) conn.send(cmd.upper()) except Exception: break conn.close() phone.close()
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('192.168.20.105',8080)) while 1: sends = input('>>:') if not sends:continue phone.send(sends.encode('utf-8')) mess = phone.recv(1024) print(mess) phone.close()
#_*_coding:utf-8_*_ __author__ = 'Linhaifeng' from socket import * import subprocess ip_port=('127.0.0.1',8080) BUFSIZE=1024 tcp_socket_server=socket(AF_INET,SOCK_STREAM) tcp_socket_server.bind(ip_port) tcp_socket_server.listen(5) while True: conn,addr=tcp_socket_server.accept() print('客戶端',addr) while True: cmd=conn.recv(BUFSIZE) if len(cmd) == 0:break res=subprocess.Popen(cmd.decode('utf-8'),shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) stderr=act_res.stderr.read() stdout=act_res.stdout.read() conn.send(stderr) conn.send(stdout)
#_*_coding:utf-8_*_ __author__ = 'Linhaifeng' import socket BUFSIZE=1024 ip_port=('127.0.0.1',8080) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) res=s.connect_ex(ip_port) while True: msg=input('>>: ').strip() if len(msg) == 0:continue if msg == 'quit':break s.send(msg.encode('utf-8')) act_res=s.recv(BUFSIZE) print(act_res.decode('utf-8'),end='')
import socket import hashlib import subprocess import os phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #重用地址 phone.bind(('192.168.20.105',8081)) phone.listen(5) while 1: conn,addr=phone.accept() print('線路是%s' % conn) print('地址是',addr) tag = True while 1: while tag: user = conn.recv(1024).decode('utf-8') pwd = conn.recv(1024).decode('utf-8') md5_obj = hashlib.md5(user.encode('utf-8')) s = pwd+user print(s) md5_obj.update(s.encode('utf-8')) pwd = md5_obj.hexdigest() print(pwd) if user == 'egon'and pwd=='82bdb4164c14585f32e70ec0a37b3569': conn.send('right'.encode('utf-8')) tag = False break else: conn.send('用戶名或密碼錯誤,請從新輸入!'.encode('utf-8')) try: cmd = conn.recv(1024) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) mes = res.stdout.read() mesr = res.stderr.read() conn.send(str(len(mes+mesr)).encode('utf-8')) conn.send(mes+mesr) except Exception: break conn.close() phone.close()
import socket import time phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('192.168.20.105',8081)) tag = True while 1: while tag: user = input('username:') pwd = input('password:') phone.send(user.encode('utf-8')) phone.send(pwd.encode('utf-8')) time.sleep(1) mes = phone.recv(1024).decode('utf-8') print(mes) if mes =='right': tag = False break cmd = input('>>:') if not cmd:continue phone.send(cmd.encode('utf-8')) lens = phone.recv(1024).decode('utf-8') mes = phone.recv(1024) while 1: if int(lens)>len(mes): mes+=phone.recv(1024) else: break print(mes.decode('gbk')) phone.close()