本文内容: socket介紹
TCP: 服務端
用戶端
UDP: 服務端
用戶端
首發時間:2018-02-08 01:14
修改: 2018-03-20 :重置了布局,增加了UDP
什麼是socket:
socket又稱"套接字",應用程式通常通過"套接字"向網絡送出請求或者應答網絡請求。
網絡上的兩個程式通過一個雙向的通信連接配接實作資料的交換,這個連接配接的一端稱為一個socket。
socket就像電話線插口,隻有電話線插上了,才能通信。
python中使用socket來進行網絡連接配接傳輸
TCP:
如果使用socket子產品來建立TCP用戶端和服務端: 首發需要導入子產品:import socket
然後建立過程在下面
服務端:
TCP服務端一般需要下面幾個操作:建立,綁定IP位址和端口,監聽端口,等待連接配接,接收資料,傳輸資料 ,關閉連接配接 建立:server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) 【參數預設就是socket.AF_INET, socket.SOCK_STREAM】
綁定端口:server.bind(('IP位址',端口)),【位址和端口号是一個 tuple 】
監聽:server.listen()
接受連接配接: conn,addr=server.accept(),傳回值是一個連接配接執行個體和一個位址,位址是連接配接過來的用戶端位址,而資料操作要利用這個連接配接執行個體
傳輸資料:conn.send(data),【傳輸的資料必須是位元組流,是以對字元串資料需要使用encode() 】
接收資料read:conn.recv(size),【傳輸的資料必須是位元組流,size是接收的位元組數,如果需要轉成Unicode,需要使用decode() 】
關閉連接配接close:close()
importsocket
server=socket.socket()#建立socket
server.bind(('localhost',1234))#綁定
server.listen()#監聽
print("開始等待。。。")
conn,addr=server.accept()#接收連接配接
print("連接配接成功")
data=conn.recv(1024)#接收資料
print(data.decode())
conn.send(data)#發送資料
server.close()#關閉連接配接
print("--------------------")
上述代碼存在一個問題:隻能接受一次連接配接,連接配接結束後,服務端socket将關閉,更改成不立即關閉能等待下一個連接配接的:
#伺服器端
importsocket
server=socket.socket()
server.bind(('localhost',1234)) #綁定ip和端口
server.listen(5) #監聽
whileTrue:print("開始等待")
conn, addr=server.accept()print(conn, addr)print("用戶端連接配接")whileTrue:
data= conn.recv(1024)print("recv:",data)if not data: #當data=0時為真
print("連接配接斷開...")breakconn.send(data)
server.close()
注:上述代碼中在linux中正常運作,在windows中會報錯!
如果要在windows中運作,需要捕獲異常:
#伺服器端
importsocket
server=socket.socket()
server.bind(('localhost',1234)) #綁定ip和端口
server.listen(5) #監聽
whileTrue:print("開始等待")
conn, addr=server.accept()print(conn, addr)print("用戶端連接配接")whileTrue:try:
data= conn.recv(1024)print("recv:",data)if not data: #當data=0時為真
print("連接配接斷開...")breakconn.send(data)exceptConnectionResetError as e:print(e)breakserver.close()
用戶端:
TCP用戶端一般需要下面幾個操作:建立socket,連接配接遠端socket,傳輸資料 ,接收資料,關閉連接配接
建立:client=socket.socket()
連接配接:client.connect(('IP位址',端口)),其中位址和端口号是一個 tuple
傳輸資料:client.send(data),傳輸的資料必須是位元組流,是以對字元串資料需要使用encode()
接收資料recv:client.recv(size),傳輸的資料是位元組流,如果需要轉成Unicode,需要使用decode()
關閉連接配接close:close()
importsocket
client=socket.socket()#建立socket
client.connect(('localhost',1234))#連接配接
client.send("你好".encode())#發送資料
data=client.recv(1024)#接收資料
print(data.decode())
client.close()#關閉連接配接
上述代碼存在一個問題:隻能發送一次資料,發生完資料就會斷開連接配接,改成可以多次發送資料,不自動斷開的【前提是服務端能接收多次】:
importsocket
client=socket.socket()
client.connect(('localhost',1234))whileTrue:
cmd=input(">>")if len(cmd)==0:continueclient.send(cmd.encode())
cmd_res=client.recv(1024)print(cmd_res.decode())
client.close()
UDP:
服務端:
UDP服務端通常有以下幾個操作:建立socket,綁定端口,傳輸資料,接收資料
建立socket:server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
綁定端口:server.bind(addr),【addr是一個元組,内容為(位址,端口)】
接收資料:data,client_addr=server.recvfrom(1024)
傳輸資料:server.sendto(data,client_addr)
importsocketimporttime
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(("localhost",1234))
start_time=time.time()whileTrue:
data,addr=server.recvfrom(1024)print(data,addr)
server.sendto("hello".encode(),addr)
time.sleep(1)if time.time()-start_time>30:breakserver.close()
用戶端:
UDP用戶端通常有以下幾個操作:建立socket,傳輸資料,接收資料
建立socket:client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
傳輸資料:server.sendto(data,addr),【addr是一個元組,内容為(位址,端口)】
接收資料:data,server_addr=client.recvfrom(1024)
importsocket,time
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
addr=("localhost",1234)
start_time=time.time()whileTrue:
client.sendto(time.ctime().encode(),addr)
data,addr= client.recvfrom(1024)print(data)
time.sleep(1)if time.time()-start_time>30:breakclient.close()