




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Python的socket與socketserver怎么使用#1、買(mǎi)手機(jī)
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#tcp稱為流式協(xié)議,udp稱為數(shù)據(jù)報(bào)協(xié)議SOCK_DGRAM
#print(phone)
#2、插入/綁定手機(jī)卡
#phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind((127.0.0.1,8080))
#3、開(kāi)機(jī)
phone.listen(5)#半連接池,限制的是請(qǐng)求數(shù)
#4、等待電話連接
print(start....)
whileTrue:#連接循環(huán)
conn,client_addr=phone.accept()#(三次握手建立的雙向連接,(客戶端的ip,端口))
#print(conn)
print(已經(jīng)有一個(gè)連接建立成功,client_addr)
#5、通信:收\(chéng)發(fā)消息
whileTrue:#通信循環(huán)
print(服務(wù)端正在收數(shù)據(jù)...)
data=conn.recv(1024)#最大接收的字節(jié)數(shù),沒(méi)有數(shù)據(jù)會(huì)在原地一直等待收,即發(fā)送者發(fā)送的數(shù)據(jù)量必須0bytes
#print(===)
iflen(data)==0:break#在客戶端單方面斷開(kāi)連接,服務(wù)端才會(huì)出現(xiàn)收空數(shù)據(jù)的情況
print(來(lái)自客戶端的數(shù)據(jù),data)
conn.send(data.upper())
exceptConnectionResetError:
break
#6、掛掉電話連接
conn.close()
#7、關(guān)機(jī)
phone.close()
#start....
#已經(jīng)有一個(gè)連接建立成功(127.0.0.1,4065)
#服務(wù)端正在收數(shù)據(jù)...
#來(lái)自客戶端的數(shù)據(jù)b\xad
#服務(wù)端正在收數(shù)據(jù)...
2、客戶端
importsocket
#1、買(mǎi)手機(jī)
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#print(phone)
#2、撥電話
phone.connect((127.0.0.1,8080))#指定服務(wù)端ip和端口
#3、通信:發(fā)\收消息
whileTrue:#通信循環(huán)
msg=input(:).strip()#msg=
iflen(msg)==0:continue
phone.send(msg.encode(utf-8))
#print(hassend-----)
data=phone.recv(1024)
#print(hasrecv-----)
print(data)
#4、關(guān)閉
phone.close()
#:啊
#ba
#:啊啊
#b\xb0\xa1\xb0\xa1
#:
3、地址占用問(wèn)題
這個(gè)是由于你的服務(wù)端仍然存在四次揮手的time_wAIt狀態(tài)在占用地址(如果不懂,請(qǐng)深入研究1.tcp三次握手,四次揮手2.syn洪水攻擊3.服務(wù)器高并發(fā)情況下會(huì)有大量的time_wait狀態(tài)的優(yōu)化方法)
1、方法一:加入一條socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#就是它,在bind前加
phone.bind((127.0.0.1,8080))
2、方法二:通過(guò)調(diào)整linux內(nèi)核參數(shù)
發(fā)現(xiàn)系統(tǒng)存在大量TIME_WAIT狀態(tài)的連接,通過(guò)調(diào)整linux內(nèi)核參數(shù)解決,
vi/etc/sysctl.conf
編輯文件,加入以下內(nèi)容:
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_fin_timeout=30
然后執(zhí)行/sbin/sysctl-p讓參數(shù)生效。
net.ipv4.tcp_syncookies=1表示開(kāi)啟SYNCookies。當(dāng)出現(xiàn)SYN等待隊(duì)列溢出時(shí),啟用cookies來(lái)處理,可防范少量SYN攻擊,默認(rèn)為0,表示關(guān)閉;
net.ipv4.tcp_tw_reuse=1表示開(kāi)啟重用。允許將TIME-WAITsockets重新用于新的TCP連接,默認(rèn)為0,表示關(guān)閉;
net.ipv4.tcp_tw_recycle=1表示開(kāi)啟TCP連接中TIME-WAITsockets的快速回收,默認(rèn)為0,表示關(guān)閉。
net.ipv4.tcp_fin_timeout修改系統(tǒng)默認(rèn)的TIMEOUT時(shí)間
4、模擬ssh遠(yuǎn)程執(zhí)行命令
服務(wù)端通過(guò)subprocess執(zhí)行該命令,然后返回命令的結(jié)果。
服務(wù)端:
fromsocketimport*
importsubprocess
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8000))
server.listen(5)
print(start...)
whileTrue:
conn,client_addr=server.accept()
whileTrue:
print(fromclient:,client_addr)
cmd=conn.recv(1024)
iflen(cmd)==0:break
print(cmd:,cmd)
obj=subprocess.Popen(cmd.decode(utf8),#輸入的cmd命令
shell=True,#通過(guò)shell運(yùn)行
stderr=subprocess.PIPE,#把錯(cuò)誤輸出放入管道,以便打印
stdout=subprocess.PIPE)#把正確輸出放入管道,以便打印
stdout=obj.stdout.read()#打印正確輸出
stderr=obj.stderr.read()#打印錯(cuò)誤輸出
conn.send(stdout)
conn.send(stderr)
conn.close()
server.close()
客戶端
importsocket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((127.0.0.1,8000))
whileTrue:
data=input(pleaseenteryourdata)
client.send(data.encode(utf8))
data=client.recv(1024)
print(fromserver:,data)
client.close()
輸入dir命令,由于服務(wù)端發(fā)送字節(jié)少于1024字節(jié),客戶端可以接受。
輸入tasklist命令,由于服務(wù)端發(fā)送字節(jié)多于1024字節(jié),客戶端只接受部分?jǐn)?shù)據(jù),并且當(dāng)你再次輸入dir命令的時(shí)候,客戶端會(huì)接收dir命令的結(jié)果,但是會(huì)打印上一次的剩余未發(fā)送完的數(shù)據(jù),這就是粘包問(wèn)題。
1、發(fā)送端需要等緩沖區(qū)滿才發(fā)送出去,造成粘包
發(fā)送數(shù)據(jù)時(shí)間間隔很短,數(shù)據(jù)量很小,會(huì)合到一起,產(chǎn)生粘包。
服務(wù)端
#_*_coding:utf-8_*_
fromsocketimport*
ip_port=(127.0.0.1,8080)
TCP_socket_server=socket(AF_INET,SOCK_STREAM)
TCP_socket_server.bind(ip_port)
TCP_socket_server.listen(5)
conn,addr=TCP_socket_server.accept()
data1=conn.recv(10)
data2=conn.recv(10)
print(-----,data1.decode(utf-8))
print(-----,data2.decode(utf-8))
conn.close()
客戶端
#_*_coding:utf-8_*_
importsocket
BUFSIZE=1024
ip_port=(127.0.0.1,8080)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex(ip_port)
s.send(hello.encode(utf-8))
s.send(world.encode(utf-8))
#服務(wù)端一起收到bhelloworld
2、接收方不及時(shí)接收緩沖區(qū)的包,造成多個(gè)包接收
客戶端發(fā)送了一段數(shù)據(jù),服務(wù)端只收了一小部分,服務(wù)端下次再收的時(shí)候還是從緩沖區(qū)拿上次遺留的數(shù)據(jù),產(chǎn)生粘包。
服務(wù)端
#_*_coding:utf-8_*_
fromsocketimport*
ip_port=(127.0.0.1,8080)
TCP_socket_server=socket(AF_INET,SOCK_STREAM)
TCP_socket_server.bind(ip_port)
TCP_socket_server.listen(5)
conn,addr=TCP_socket_server.accept()
data1=conn.recv(2)#一次沒(méi)有收完整
data2=conn.recv(10)#下次收的時(shí)候,會(huì)先取舊的數(shù)據(jù),然后取新的
print(-----,data1.decode(utf-8))
print(-----,data2.decode(utf-8))
conn.close()
客戶端
#_*_coding:utf-8_*_
importsocket
BUFSIZE=1024
ip_port=(127.0.0.1,8080)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex(ip_port)
s.send(hellofeng.encode(utf-8))
6、解決粘包問(wèn)題
1、先發(fā)送的字節(jié)流總大小(low版)
問(wèn)題的根源在于,接收端不知道發(fā)送端將要傳送的字節(jié)流的長(zhǎng)度,所以解決粘包的方法就是圍繞,如何讓發(fā)送端在發(fā)送數(shù)據(jù)前,把自己將要發(fā)送的字節(jié)流總大小讓接收端知曉,然后接收端來(lái)一個(gè)死循環(huán)接收完所有數(shù)據(jù)。
為何low:程序的運(yùn)行速度遠(yuǎn)快于網(wǎng)絡(luò)傳輸速度,所以在發(fā)送一段字節(jié)前,先用send去發(fā)送該字節(jié)流長(zhǎng)度,這種方式會(huì)放大網(wǎng)絡(luò)延遲帶來(lái)的性能損耗。
服務(wù)端:
importsocket,subprocess
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((127.0.0.1,8000))
server.listen(5)
whileTrue:
conn,addr=server.accept()
print(start...)
whileTrue:
cmd=conn.recv(1024)
print(cmd:,cmd)
obj=subprocess.Popen(cmd.decode(utf8),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout=obj.stdout.read()
ifstdout:
ret=stdout
else:
stderr=obj.stderr.read()
ret=stderr
ret_len=len(ret)
conn.send(str(ret_len).encode(utf8))
data=conn.recv(1024).decode(utf8)
ifdata==recv_ready:
conn.sendall(ret)
conn.close()
server.close()
客戶端:
importsocket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((127.0.0.1,8000))
whileTrue:
msg=input(pleaseenteryourcmdyouwant).strip()
iflen(msg)==0:continue
client.send(msg.encode(utf8))
length=int(client.recv(1024))
client.send(recv_ready.encode(utf8))
send_size=0
recv_size=0
data=b
whilerecv_sizelength:
data=client.recv(1024)
recv_size+=len(data)
print(data.decode(utf8))
2、自定義固定長(zhǎng)度報(bào)頭(struct模塊)
struct模塊解析
importstruct
importjson
#i是格式
obj=struct.pack(i,1222222222223)
exceptExceptionase:
print(e)
obj=struct.pack(i,1222)
print(obj,len(obj))
#iformatrequires-2147483648=number=2147483647
#b\xc6\x04\x00\x004
res=struct.unpack(i,obj)
print(res[0])
#1222
解決粘包問(wèn)題的核心就是:為字節(jié)流加上自定義固定長(zhǎng)度報(bào)頭,報(bào)頭中包含字節(jié)流長(zhǎng)度,然后一次send到對(duì)端,對(duì)端在接收時(shí),先從緩存中取出定長(zhǎng)的報(bào)頭,然后再取真實(shí)數(shù)據(jù)。
1、使用struct模塊創(chuàng)建報(bào)頭:
importjson
importstruct
header_dic={
filename:a.txt,
total_size:111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223131232,
hash:asdf123123x123213x
header_json=json.dumps(header_dic)
header_bytes=header_json.encode(utf-8)
print(len(header_bytes))#223
#i是格式
obj=struct.pack(i,len(header_bytes))
print(obj,len(obj))
#b\xdf\x00\x00\x004
res=struct.unpack(i,obj)
print(res[0])
#223
2、服務(wù)端:
fromsocketimport*
importsubprocess
importstruct
importjson
server=socket(AF_INET,SOCK_STREAM)
server.bind((127.0.0.1,8000))
server.listen(5)
print(start...)
whileTrue:
conn,client_addr=server.accept()
print(conn,client_addr)
whileTrue:
cmd=conn.recv(1024)
obj=subprocess.Popen(cmd.decode(utf8),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stderr=obj.stderr.read()
stdout=obj.stdout.read()
#制作報(bào)頭
header_dict={
filename:a.txt,
total_size:len(stdout)+len(stderr),
hash:xasf123213123
header_json=json.dumps(header_dict)
header_bytes=header_json.encode(utf8)
#1.先把報(bào)頭的長(zhǎng)度len(header_bytes)打包成4個(gè)bytes,然后發(fā)送
conn.send(struct.pack(i,len(hea
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 體育場(chǎng)館運(yùn)動(dòng)地板安裝與維修服務(wù)市場(chǎng)分析考核試卷
- 靜電防護(hù)操作風(fēng)險(xiǎn)控制考核試卷
- 吊頂安全考試題及答案
- sqoop面試題及答案
- 家電行業(yè)電子商務(wù)平臺(tái)運(yùn)營(yíng)考核試卷
- java工程師面試題及答案jvm
- 永青集團(tuán)考試試題及答案
- 跳舞主播考試試題及答案
- 小區(qū)反應(yīng)測(cè)試題及答案
- 城鎮(zhèn)化課件2024-2025學(xué)年高一地理人教版(2019)必修二
- 2025年金融科技企業(yè)估值方法與投資策略在金融科技企業(yè)并購(gòu)中的應(yīng)用案例報(bào)告
- 福建省廈門(mén)市雙十中學(xué)2025屆七年級(jí)生物第二學(xué)期期末聯(lián)考模擬試題含解析
- 【小學(xué)】新蘇教版小學(xué)數(shù)學(xué)四年級(jí)下冊(cè)暑假每日一練(02):計(jì)算題-應(yīng)用題(含答案)
- 2025豬藍(lán)耳病防控及凈化指南(第三版)
- TCUWA20059-2022城鎮(zhèn)供水管網(wǎng)模型構(gòu)建與應(yīng)用技術(shù)規(guī)程
- 2025至2030中國(guó)壓縮空氣儲(chǔ)能產(chǎn)業(yè)現(xiàn)狀調(diào)查及項(xiàng)目投資策略建議報(bào)告
- 三臺(tái)縣2024-2025學(xué)年小學(xué)六年級(jí)數(shù)學(xué)畢業(yè)檢測(cè)指導(dǎo)卷含解析
- 宅基地互換合同協(xié)議書(shū)范本
- 2025人教版數(shù)學(xué)四年級(jí)下冊(cè) 第一單元《四則運(yùn)算》單元分層作業(yè)
- 園藝植物育種學(xué)知到課后答案智慧樹(shù)章節(jié)測(cè)試答案2025年春浙江大學(xué)
- 集團(tuán)公司下屬子公司管理制度
評(píng)論
0/150
提交評(píng)論