Python-socket總結
- 2020 年 1 月 6 日
- 筆記
socket是什麼
什麼是socket所謂socket通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的句柄。
應用程式通常通過"套接字"向網路發出請求或者應答網路請求。說白了就是一種通訊機制。
列入你和移動客服諮詢問題時,會有一個客服為你解決問題一樣,就是你和客服間的相互通訊
在socket里就是「發送」和「接收」這兩個動作就是socket通訊方式
socket.gethostname() # 獲取主機名
from socket import * # 避免 socket.socket()
s=socket()
s.bind() # 綁定地址到套接字
s.listen() # 開始TCP監聽
s.accept() # 被動接受TCP客戶端連接,等待連接的到來
s.connect() # 主動初始化TCP伺服器連接
s.connect_ex() # connect()函數的擴展版本,出錯時返回出錯碼,而不是跑出異常
s.recv() # 接收TCP數據
s.send() # 發送TCP數據
s.sendall() # 完整發送TCP數據
s.recvfrom() # 接收UDP數據
s.sendto() # 發送UDP數據
s.getpeername() # 連接到當前套接字的遠端的地址(TCP連接)
s.getsockname() # 當前套接字的地址
s.getsockopt() # 返回指定套接字的參數
s.setsockopt() # 設置指定套接字的參數
s.close() # 關閉套接字
s.setblocking() # 設置套接字的阻塞與非阻塞模式
s.settimeout() # 設置阻塞套接字操作的超時時間
s.gettimeout() # 得到阻塞套接字操作的超時時間
s.filen0() # 套接字的文件描述符
s.makefile() # 創建一個與該套接字關聯的文件對象
socket.AF_UNIX # 只能夠用於單一的Unix系統進程間通訊
socket.AF_INET # 伺服器之間網路通訊
socket.AF_INET6 # IPv6
socket.SOCK_STREAM # 流式socket , for TCP
socket.SOCK_DGRAM # 數據報式socket , for UDP
socket.SOCK_RAW # 原始套接字,普通的套接字無法處理ICMP、IGMP等網路報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。
socket.SOCK_RDM # 是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在需要執行某些特殊操作時使用,如發送ICMP報文。SOCK_RAM通常僅限於高級用戶或管理員運行的程式使用。
socket.SOCK_SEQPACKET # 可靠的連續數據包服務
基礎講解
# 創建socket對象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 監聽埠
sock.bind(('127.0.0.1',8001))
# 開始監聽,
sock.listen(5)
while True:
# 阻塞,deng 。。。。
# 直到有請求連接
print '….'
connection, address = sock.accept()
# connection,代表客戶端socket對象,
# address,客戶端IP地址
#handle_request(connection)
buf = connection.recv(1024)
print buf
connection.send("HTTP/1.1 200 OKrnrn")
connection.send("Hello, World")
connection.close()
#服務端
import socket
HOST='' #空代表0.0.0.0
PORT= 6666 #監聽埠
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)
while True:
conn,addr= s.accept()
print'Connected by', addr
while True:
data = conn.recv(1024) #接收1024位元組數據
if not data: break #如果收不到客戶端數據了(代表客戶端斷開了),就斷開
conn.sendall(data.upper()) #將收到的數據全變成大寫再發給客戶端
conn.close() #關閉此客戶端的連接實例
#客戶端
import socket
HOST=''
PORT= 6666 #監聽埠
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)
while True:
conn,addr= s.accept()
print'Connected by', addr
while True:
data = conn.recv(1024) #接收1024位元組數據
if not data: break #如果收不到客戶端數據了(代表客戶端斷開了),就斷開
conn.sendall(data.upper()) #將收到的數據全變成大寫再發給客戶端
conn.close() #關閉此客戶端的連接實例
服務端socket在使用bind方法之後調用listen方法去監聽一個給定的 地址。然後,客戶端socket就可以通過使 用 connect方法(connect方法所使用的地址參數與bind相同)去連接服務端。listen方法 要求一個參數,這個參數就是等待連接隊列中所能包含的連接數。
一旦服務端socket調用了listen方法,就進入了臨聽狀態,然後通 常使用一個無限的循環:1、開始接受客房端的連接,這通過調用accept方法來實現。調用了這個方法後將處於阻塞狀態(等待客戶端發起連接)直到一個客 戶端連接,連接後,accept返回形如(client,address)的一個元組,其中client是一個用於與客戶端通訊的 socket,address是客戶端的形如xxx.xxx.xxx.xxx:xxx的地址;2、然後服務端處理客戶端的請求;3、處理完成之後又調用 1。
#以上例子是單執行緒的只能一對一的服務,即服務端只能處理一個鏈接,想要處理多執行緒怎麼辦,不用急多執行緒的Python已給我們寫好直接調用就好
socket服務端
#用於處理多執行緒的模組
import SocketServer
import os
class MyTCP(SocketServer.BaseRequestHandler):
def handle(self):
while True:
self.data=self.request.recv(1024).strip() #接受數據
if self.data == 'quit' or not self.data:break #如果沒有數據或為quit 退出
cmd_data=os.popen(self.data).read() #將命令結果存為字元串
if cmd_data == '':cmd_data= self.data + ': Command not found' #如果命令結果為空或命令返回為空
self.request.sendall(cmd_data) #發送所有的數據
if __name__ == '__main__':
HOST,PORT = '127.0.0.1',6666 #綁定埠和ip
server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCP) #將寫的類加入多執行緒處理
server.serve_forever() #循環啟動
socket客戶端
import socket
HOST='127.0.0.1'
PORT=6666
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #服務期間的TCP通訊
s.connect((HOST,PORT)) #綁定埠和ip
while True:
while True: #如果命令為空繼續輸入
cmd=raw_input('CMD:').strip()
if cmd != '':break
s.sendall(cmd) #發送所有數據
data=s.recv(1024).split('n') #以換行符分割接收的數據
print 'cmd:'
for line in data:print line #循環列印數據
s.close() #關閉套接字
用SocketServer創建一個伺服器需要三步:
1、通過子類化BaseRequestHandler類和覆蓋它的handle()方法來創建一個請求處理器類,用於處理進來
的請求; 2、實例化服務類如TCPServer,並傳遞給它參數:伺服器地址和請求處理器類; 3、調用服務實例對象的handle_request()或serve_forever()方法去處理請求。