python socket編程,pythonsocket
每天寫一點,總有一天我這條鹹魚能變得更鹹
檔案參考:點擊這裡(http://www.cnblogs.com/aylin/p/5572104.html)
主要內容:
1.socket
2.socketserver
一. socket
socket簡介
socket起源與Unix,而Unix/Linux基本哲學之一就是"一切皆檔案",對於檔案用【開啟】【讀寫】【關閉】模式來操作,socket的實現模式也是如此,可以看成是一種特殊的檔案模式,建立串連,發送訊息,關閉串連,其具體過程如所示:
代碼執行個體如下:
服務端
import socketport = 8888host = "127.0.0.1"#建立通訊端描述字元sk = socket.socket()#命名通訊端sk.bind((host,port))#監聽用戶端的請求sk.listen(5)while True: #等待用戶端串連,阻塞過程 conn,address = sk.accept() #給予用戶端響應 conn.send("welcom!!!!!\n") while True: #接收用戶端訊息 content = conn.recv(1024) if content == "exit": break else: data = raw_input("please input:") #回應訊息給用戶端 conn.send(data)server
用戶端
import sockethost = "127.0.0.1"port = 8888#建立通訊端符描述cl = socket.socket()#串連服務端cl.connect((host,port))while True: #接收服務端響應 content = cl.recv(1024) flag = 1 while flag: data = raw_input("please input:") # 發送訊息到服務端 cl.send(data) if data == "exit": flag = 0 else: content = cl.recv(1024) #關閉串連 cl.close() breakclient
server一些常用的函數
sk.bind(address)
將通訊端綁定到地址,地址需要以元組的形式傳入
sk.listen(n)
監聽地址,n指可以掛起的最大串連數量,n的最大值為5
sk.accpet()
接受用戶端串連請求並返回(conn,address),其中conn是新的通訊端對象,可用來與用戶端之間互動。address是用戶端的地址,該步驟是阻塞的,會一直等待接收到用戶端的串連請求
sk.close()
關閉串連
sk.connect(address)
串連到address處的通訊端,address的格式為元組,串連出錯則拋出socket異常
sk.connect_ex(address)
同上,只是串連錯誤返回編碼
sk.recv(bufsize)
接受通訊端的資料。資料以字串形式返回,bufsize指定最多可以接收的數量
sk.recvfrom(bufsize)
與recv()類似,但是傳回值為元組(data,address)
sk.send(string)
發送資料,傳回值為已發送資料的長度,可能小於string的長度
sk.sendall(string)
發送資料,所有資料全部發送則返回None,發送失敗則拋出異常
sk.sendto(string,address)
向指定的地址發送資料
sk.settimeout(timeout)
設定通訊端操作的逾時期,單位為s,類型為浮點型
關於socket的簡單的執行個體
TCP檔案上傳:
import socketimport sysimport osip_port = ('127.0.0.1', 8888)sk = socket.socket()sk.connect(ip_port)container = {'key': '', 'data': ''}while True: input = raw_input('path:') cmd, path = input.split('|') file_name = os.path.basename(path) file_size = os.stat(path).st_size sk.send(cmd + "|" + file_name + '|' + str(file_size)) send_size = 0 f = file(path, 'rb') Flag = True while Flag: if send_size + 1024 > file_size: data = f.read(file_size - send_size) Flag = False else: data = f.read(1024) send_size += 1024 sk.send(data) f.close()sk.close()用戶端
import socketdef recv_data(): port = 8888 host = "127.0.0.1" # 建立通訊端描述字元 sk = socket.socket() # 命名通訊端 sk.bind((host, port)) # 監聽用戶端的請求 sk.listen(5) conn, address = sk.accept() while True: pre_data = conn.recv(1024) # 擷取要求方法、檔案名稱、檔案大小 cmd, file_name, file_size = pre_data.split('|') # 已經接收檔案的大小 recv_size = 0 # 上傳檔案路徑拼接 f = file("b.txt", 'wb') Flag = True while Flag: # 未上傳完畢, if int(file_size) > recv_size: # 最多接收1024,可能接收的小於1024 data = conn.recv(1024) recv_size += len(data) # 上傳完畢,則退出迴圈 else: recv_size = 0 Flag = False continue # 寫入檔案 f.write(data) print 'upload successed.' f.close()if __name__ == "__main__": recv_data()服務端
UDP:
import socketaddress = ("127.0.0.1",8880)cl = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)while True: data = raw_input("input:") if data == "exit": break cl.sendto(data,address)client
import socketaddress=("127.0.0.1",8880)sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)sk.bind(address)while True: data = sk.recv(1024) print dataserver
一. socketserver
socket的局限在於接收資料的過程是阻塞的,也就是說socket模組之間的通訊是一對一的,舉個例子來說,就像你打電話給給A的同時,A正在和B通話,你只有等待AB通話結束了,才能與A建立串連,這樣顯然是無法滿足服務端的需求,但是socketserver確可以滿足以上的需求
流程圖大概如下:
socketserver 就是能處理多個用戶端請求的Socket服務端。因為每個用戶端請求過來的時候,服務端會建立一個線程,通過這個線程與用戶端進行通訊
執行個體如下:
import socketobj = socket.socket()obj.connect(("127.0.0.1",8080))ret_bytes = obj.recv(1024)ret_str = str(ret_bytes)print(ret_str)while True: inp = raw_input("你好請問您有什麼問題? \n >>>") if inp == "exit": obj.sendall(bytes(inp)) break else: obj.sendall(bytes(inp)) ret_bytes = obj.recv(1024) ret_str = str(ret_bytes) print(ret_str)用戶端
import socketserverclass Myserver(socketserver.BaseRequestHandler): def handle(self): conn = self.request conn.sendall("你好,我是機器人") while True: ret_bytes = conn.recv(1024) if ret_bytes == "exit": break conn.sendall("你好我好大家好")if __name__ == "__main__": server = socketserver.ThreadingTCPServer(("127.0.0.1",8080),Myserver) server.serve_forever()服務端