應用socket 的常用方法
socket 介紹
socket套接字
python 中提供了socket.py標準庫,非常底層的介面
socket是一種通用的網路程式設計介面,和網路層次沒有一一對應的關係
協議族af表示address family,用於socket()第乙個引數
名稱含義
af_inet
ipv4
af_inet6
ipv6
af_unix
unix domain socket,windows沒有
socket 型別
名稱含義
sock_stream
面向連線的流套接字,預設值,tcp協議
sock_dgram
無連線的資料報文套接字,udp協議
tcp程式設計
socket程式設計,需要兩端,一般來說需要乙個服務端,乙個客戶端,服務端稱為server,客戶端稱為client.
這種模式稱為cs程式設計.
tcp服務端程式設計
服務端程式設計步驟
)#建立socket物件
s.bind(
('127.0.0.1'
,9999))
#乙個位址和埠的二元組
s.listen(
)#開始監聽,等待客戶端連線到來
s1,info1 = s.accept(
)#阻塞,直到和客戶端成功建立連線,返回乙個新的socket物件和客戶端位址
data = s1.recv(
1024
)#阻塞,新socket物件等待獲取資料
(data)
s1.send(b'asd'
)s1.close(
)#檢視監聽埠 netstat-tan1 tcp |findstr 9999
寫乙個群聊程式
伺服器應該具有的功能:
啟動服務,包括繫結位址和埠,並監聽
建立連線,能和多個客戶端建立連線
接收不同使用者的資訊
分發,將接收的某個使用者的資訊**到已連線的所有客戶端
停止服務
記錄連線的客戶端
import socket
import threading
import logging
logging.basicconfig(level=logging.info,
format
="%(message)s"
)class
chatserver
:def
__init__
(self,ip=
'127.0.0.1'
,port=
9999):
self.sock = socket.socket(
) self.ip = ip
self.port = port
self.clients =
#建立客戶端字典
self.event = threading.event(
) self.lock = threading.lock(
)def
start
(self)
: self.sock.bind(
(self.ip,self.port)
)#例項繫結
self.sock.listen(
)#例項開始監聽
threading.thread(target=self.accept)
.start(
)#建立新執行緒並啟動
defaccept
(self)
:while
not self.event.is_set():
s1,clientinfo = self.sock.accept(
) f = s1.makefile(
'rw'
)#建立乙個與該套接字相關連的檔案物件,將recv方法看做讀方法,將send方法看做寫方法
with self.lock:
self.clients[clientinfo]
= f,s1
threading.thread(target=self.recv,args=
(f,clientinfo)
).start(
) logging.info(
(clientinfo[0]
,'已上線'))
defrecv
(self,f,client)
:while
not self.event.is_set():
try:
#捕獲異常,客戶端主動掉線將會產生異常,需要處理
data = f.read(5)
except exception as e:
logging.error(e)
data =
'quit'
with self.lock:
if data ==
''or data ==
'quit'
: _,s1 = self.clients.pop(client)
f.close(
) s1.close(
)print
('{}已下線'
.format
(client[0]
))break
for i,_ in self.clients.values():
i.write(data)
i.flush(
) logging.info(data)
defstop
(self)
: self.event.
set(
)with self.lock:
for i,j in self.clients.values():
i.close(
) j.close(
)# print('-------')
self.sock.close(
)# print('~~~~~~~~~')
chat = chatserver(
)chat.start(
)while
true
: cmd =
input
('...'
).strip(
)if cmd ==
'quit'
: chat.stop(
) threading.event(
).wait(3)
break
客戶端主動斷開帶來的問題服務端知道自己何時斷開,如果客戶端斷開,伺服器不知道。(客戶端主動斷開,服務端recv會得到乙個空串)所以,好的做法是,客戶端斷開發出特殊訊息通知伺服器端斷開連線。但是,如果客戶端主動斷開,服務端主動傳送乙個空訊息,超時返回異常,捕獲異常並清理連線。即使為客戶端提供了斷開命令,也不能保證客戶端會使用它斷開連線。但是還是要增加這個退出功能
名稱含義
socket.recv(bufsize[,flags])
獲取資料,預設是阻塞的方式
socket.recvfrom(bufsize[,flags])
獲取資料,返回乙個二元組(bytes,address)
socket.recv_into(buffer[,nbytes[,flags]])
獲取到nbytes的資料後,儲存到buffer中,如果bbytes沒有指定或0,將buffer大小的資料存入buffer中,返回接收到的位元組
socket.send(bytes[,flags])
tcp傳送資料
socket.sendall(bytes[,flags])
tcp傳送全部資料,成功返回none
socket.sendto(srting[,flag],address)
udp傳送資料
socket.sendfile(file,offset=0,count=none)
傳送乙個檔案直到eof,使用高效能的os.sendfile機制,返回傳送的位元組數,如果win下不支援sendfile,或者不是普通檔案,使用send()傳送檔案,offset告訴起始位置,
socket.getpeername()
socket.getsockname()
返回套接字自己的位址。通常是乙個元組(ipaddr,port)
socke.setblocking(flag)
如果flag為0 則將套接字設定為非阻塞魔術,否則將套接字設定為阻塞魔術(預設值),非阻塞魔術下如果呼叫recv()沒有返現任何資料,或send()呼叫無法立即傳送資料,那麼將引起socket.error異常
socket.settimeout(value)
設定套接字操作的超時期,timeout是乙個浮點數,單位是秒。值為none表示沒有超時期。一般,超時期應該在剛建立套接字時設定,因為它們可能用於連線的操作(如connect())
ocket.setsockopt(level,optname,value)
設定套接字選項的值。比如緩衝區大小。太多了,去看文件。不同系統,不同版本都不盡相同
makefile
socket.makefile(mode=『r』,buffering=none,*,encoding=none,errors=none,newline=none)
建立乙個與該套接字相關連的檔案物件,將recv方法看做讀方法,將send方法看做寫方法
python網路程式設計基礎
客戶 伺服器架構 伺服器 是乙個軟體或硬體,用於提供客戶需要的 服務 伺服器存在的唯一目的就是等待客戶的請求,給這些客戶服務,然後再等待其他的請求.常見的服務型別 硬體的客戶 伺服器架構 印表機,檔案伺服器 軟體客戶 伺服器架構 web伺服器,資料庫伺服器,視窗伺服器 gui 套接字 用於程序間通訊...
python 網路程式設計基礎
python實在是太方便,太易用了,三方庫的支援又全,語法又簡單,對開發人員來說,實在是居家旅行,x的必備利器。週末研究了下python的網路支援,做一下記錄,以備隨後翻閱。python支援bsd的socket進行網路程式設計,其api跟c中的大同小異,先看看tcp方式的,說到網路程式設計,肯定會設...
python網路程式設計基礎
目錄 標籤 空格分隔 網路程式設計 目錄tcp和udp tcp的使用是面向連線的,即資料的傳輸必須基於虛鏈路的完整建立。虛鏈路的建立提供了很多優秀的功能,比如確認重傳以保證資料的完整性,滑動視窗以保證資料傳輸的高效性,各類選項字段提供不同的可選功能。tcp的缺點是報頭大,因為需要包含比udp更多的功...