Python,socket程式設計

2022-08-31 21:00:13 字數 3761 閱讀 1006

應用層協議做的事不同,但都離不開資料的交換,本質上都是收和發~

為什麼要三次握手?

目標機器可能不存在,握手期間,傳送方也可能down掉。

客戶端————伺服器,先發請求的那個是客戶端,客戶端傳送的資訊的埠是隨機的。。伺服器端的埠是固定的

先要有接收端,相當於伺服器

接收端要申請埠號,服務要啟動正常執行開始監聽該埠

相當於網路層的乙個東西

socket.af_unix unix本機程序間通訊

socket.af_inet ipv4

socket.af_inet6 ipv6

a程序和b程序想通訊,沒有網路的情況下。

a先dump,b再load。通過硬碟的話速度慢,預設在記憶體中a程序是不能訪問b程序資料的,想快速通訊可以借助af_unix,本地啟動乙個socket在七層協議裡轉一圈

a程序傳給b

socket.sock_stream #for tcp

socket.sock_dgram #for udp

socket.sock_raw

#原始套接字,普通的套接字無法處理icmp、igmp等網路報文,而sock_raw可以;

其次,sock_raw也可以處理特殊的ipv4報文;此外,利用原始套接字,可以通過ip_hdrincl套接字選項由使用者構造ip頭。

牛逼了可以偽造ip位址,ddos攻擊,洪水攻擊,傳送大量請求導致服務關閉

a訪問b要三次握手,a發第一次,後a改自己的ip再發請求,b的回應到不了a

導致b端該連線出現掛起,a再改ip位址發請求..再掛起..

socket.sock_rdm

#是一種可靠的udp形式,即保證交付資料報但不保證順序。sock_ram用來提供對原始協議的低階訪問,

在需要執行某些特殊操作時使用,如傳送icmp報文。sock_ram通常僅限於高階使用者或管理員執行的程式使用。

socket.sock_seqpacket #廢棄了

例項:先啟動伺服器監聽埠,再啟動客戶端:

#

伺服器import

socket

server =socket.socket()

server.bind((

"localhost

",7000))#

只是繫結要監聽的埠

server.listen() #

監聽,我要監聽這個埠

print("

我開始監聽7000埠了---")

conn,addr = server.accept() #

等**,conn就是連線例項,addr為源ip位址隨機的

print("

請求來了")

#data = server.recv(1024) #接收1024

#通話中又來乙個**要切換,server.switch()要知道先後順序,可以給每個請求標記就是上面的conn

data = conn.recv(1024)

print("

recv:

",data)

conn.send(data.upper())

server.close()

'''輸出:

我開始監聽7000埠了---

請求來了

recv: b'helloworld'

'''

#

客戶端import

socket

client =socket.socket()

#宣告socket型別,同時生成socket物件

#定義協議型別預設是family=af_inet, type=sock_stream

client.connect(("

localhost

",7000))

client.send(b

"helloworld")

data = client.recv(1024)

print("

recv:

", data)

client.close()

#輸出:recv: b'helloworld'

可以看出上面這種,客戶端和伺服器端說一句話就斷了,那麼我想不停地通訊怎麼辦呢?????可以加上死迴圈

#

伺服器import

socket

server =socket.socket()

server.bind((

"localhost

",7000))

server.listen()

print("

我開始監聽7000埠了---")

conn,addr =server.accept()

print("

請求來了")

while

true:

data = conn.recv(1024)

print("

recv:

",data)

conn.send(data.upper())

server.close()

#

客戶端import

socket

client =socket.socket()

client.connect((

"localhost

",7000))

while

true:

msg = input("

>>:

").strip()

client.send(msg.encode(

"utf8"))

data = client.recv(1024)

print("

recv:

", data.decode())

client.close()

perfect~~~試了幾次之後。。。

又發現乙個問題:客戶端斷了伺服器端為什麼也斷了?

windows伺服器出錯:connectionreseterror: [winerror 10054] 遠端主機強迫關閉了乙個現有的連線。

linux伺服器:會進入進入死迴圈,recv不到資料(recv到""空),可以伺服器端判斷data接收的是否為空,是空break死迴圈

那麼請問,該如何讓某乙個客戶端斷了之後其他客戶端可以繼續連線呢?

先試試。。可以再在conn上加一層死迴圈

,加了之後windows還是報10054的錯誤,linux裡面只能乙個通話,另乙個佔線(掛起),上乙個斷開了才能跟掛起的那個通話

客戶端如果發乙個空過去(直接回車),就卡死了,怎麼回事呢?是伺服器沒收到還是什麼呢?

所以不能send空,不能send空,不能send空,重要的事說三遍。。。所以就要在客戶端判斷一下

那麼可以把客戶端模擬成ssh呢?

伺服器端搞成os.popen().read()就可以了,如果某命令執行結果超過1024byte,客戶端還在繼續發命令。。那麼伺服器端還是會不停執行

但客戶端每次只能接收1024位元組,資料全存在緩衝區排隊了

那麼,讓客戶端一次能接收很大的資料會怎樣呢???

發乙個大檔案,雖然客戶端一次可以接很大,但是伺服器端每次只能發32768,依據作業系統而定,so

讓客戶端全發,迴圈發sendall()會怎樣呢?

但是神奇了,客戶端接收開始有限制了,好像每次最多10m,依系統區別這個也有區別(在centos上試的,而有的系統還會出錯)

so...看來。。。沒辦法一次收過來,頻寬有限制,網絡卡也有限制。。recieve有限制的,send也有限制的。

Python Socket 程式設計

client import socket,sys if name main 處理引數 argv sys.argv if len argv 3 or len argv 2 and argv 1 print useage argv 0 sys.exit 0 host argv 1 server ip位址...

python socket程式設計

python 編寫server的步驟 1.第一步是建立socket物件。呼叫socket建構函式。如 socket socket.socket family,type family引數代表位址家族,可為af inet或af unix。af inet家族包括internet位址,af unix家族用於...

python socket程式設計

客戶端 author lenovo fromsocketimport host localhost port 2157 bufsize 1024 addr host,port tcpclient socket af inet,sock stream tcpclient.connect addr wh...