python之網路程式設計1-socket-tcp與udp
阿新 • • 發佈:2018-12-10
一、概念
兩個獨立python檔案之間可以通過寫入檔案,讀取檔案進行互動
由於不同機器上的程式要通訊,才產生了網路
B/S架構統一入口,各種小程式和公眾號
服務端 一直執行,等待服務別人
客戶端 用的時候,才使用服務
想要實現通訊
網絡卡 和 網線
網絡卡上有全球唯一的mac地址(實體地址)
4個點分十進位制
4個八位二進位制:00000000.00000000.00000000.00000000
0.0.0.0-255.255.255.255
通過ip地址就能找到對應的mac地址:遵循arp協議
交換機-多臺機器間的通訊問題:廣播風暴
閘道器:區域網中的機器想要訪問區域網外的機器,需要通過閘道器訪問
子網掩碼與IP地址進行按位與 運算 得到網段地址:可判斷電腦是否在同一個網段內
埠:找到的程式
在同一時間只會有一個程式佔用一個埠
不可能在同一時間 有兩個程式 佔用同一個埠
埠範圍:0-65535
一般用8000之後的埠
ip:確定唯一一臺機器
127.0.0.1 本地的迴環地址
埠:確定唯一的一個程式
ip+埠:找到唯一的一臺機器上的唯一的一個程式
二、socket初認識
server端:
#server端 import socket sk=socket.socket() #sk為手機物件 # sk.bind('ip','port') #繫結手機號 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 避免服務重啟的時候報address already in use sk.bind(('127.0.0.1',8080)) sk.listen() # 監聽。等電話過程 conn,addr=sk.accept() #接收到別人電話 connection連線,與它連線的address地址 print(addr) while True: # ret=conn.recv(1024) # 聽別人說話 # print(ret) # conn.send(b'hi') # 我和別人說話,必須傳一個bytes型別 # ret=conn.recv(1024) # print(ret.decode('utf-8')) # conn.send(bytes('大碗油潑面',encoding='utf-8')) ret=conn.recv(1024).decode('utf-8') if ret=='bye': break print(ret) info=input('>>>') conn.send(bytes(info,encoding='utf-8')) conn.close() #掛電話 sk.close() #關手機
client端:
# client端 import socket sk=socket.socket() #買手機 sk.connect(('127.0.0.1',8080)) #撥別人的號 while True: # sk.send(b'hello') # ret=sk.recv() # print(ret) # sk.send(bytes('中午吃什麼?'.encode('utf-8'))) # ret=sk.recv(1024) # print(ret.decode('utf-8')) info=input(">>>") sk.send(bytes(info,encoding='utf-8')) ret=sk.recv(1024).decode('utf-8') print(ret) if ret=='bye': sk.send(b'bye') break sk.close()
三、socket之udp和tcp
TCP-demo:
server端:
#server端
import socket
sk=socket.socket() #買手機 建立一個socket物件
sk.bind(('127.0.0.1',8080)) #繫結ip和埠,啟動服務
sk.listen() #寫幾就是幾個,不寫就是不限制
conn,addr=sk.accept() #獲取到一個客戶端的連線,已經完成了三次握手
# 阻塞
# msg = conn.recv(1024) # 阻塞
# print(msg.decode('utf-8'))
while True:
info=input('>>>')
if info=='bye':
conn.send(b'bye') # 發訊息
break
conn.send(info.encode('utf-8')) #發訊息
ret=conn.recv(1024).decode('utf-8')
if ret=='bye':
break
print(ret)
conn.close()
sk.close() #關閉socket物件,如果不關閉,還能繼續接收
client端:
# client端
import socket
sk=socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
msg=input('>>>')
if msg=='bye':
sk.send(b'bye')
break
sk.send(msg.encode('utf-8'))
ret=sk.recv(1024).decode('utf-8')
if ret=='bye':
break
print(ret)
sk.close()
UDP-demo:
server端:
# server端
import socket
sk=socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8080))
msg,addr=sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.sendto(b'bye',addr)
# udp的server不需要監聽和建立連線
# 而是在啟動服務後,只能被動的等待客戶端傳送訊息過來
# 客戶端傳送訊息的同時還會 自帶地址資訊
# 訊息回覆時,不僅需要傳送訊息,還需要把對方的地址傳送過去
client端:
# client端
import socket
sk=socket.socket(socket.SOCK_DGRAM)
ip_port=('127.0.0.1',8080)
sk.sendto(b'hello',ip_port)
ret,addr=sk.recvfrom(1024)
print(ret.decode('utf-8'))
sk.close()
四、利用udp實現qq聊天功能:
server:
import socket
sk=socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8080))
while True:
msg,addr=sk.recvfrom(1024)
print(addr)
print(msg.decode('utf-8'))
info=input('>>>').encode('utf-8')
sk.sendto(info,addr)
sk.close()
client1:
import socket
sk=socket.socket(type=socket.SOCK_DGRAM)
ip_port=('127.0.0.1',8080)
while True:
# info=input("tiger哥:").encode('utf-8')
info = input("tiger哥:")
info=('\033[34m來自tiger哥的訊息 %s\033[0m'%info).encode('utf-8')
sk.sendto(info,ip_port)
msg,addr=sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.close()
client2:
import socket
sk=socket.socket(type=socket.SOCK_DGRAM)
ip_port=('127.0.0.1',8080)
while True:
# info=input("二哥:").encode('utf-8')
info = input("二哥:")
info=('\033[32m來自二哥的訊息 %s\033[0m'%info).encode('utf-8')
sk.sendto(info,ip_port)
msg,addr=sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.close()
五:UDP實現時間轉換
server端:
# 需求
# 寫一個時間同步的伺服器
# 服務端接收請求
# 按照client端傳送的時間格式,將伺服器時間轉換成對應格式
# 傳送給客戶端
import socket
import time
sk=socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9000))
while True:
msg,addr=sk.recvfrom(1024)
time_format=msg.decode('utf-8')
time_str=time.strftime(time_format)
sk.sendto(time_str.encode("utf-8"),addr)
sk.close()
client端:
import socket
sk=socket.socket(type=socket.SOCK_DGRAM)
sk.sendto('%Y-%m-%d %H-%M-%S'.encode('utf-8'),('127.0.0.1',9000))
msg,addr=sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.close()