1. 程式人生 > >python之網路程式設計1-socket-tcp與udp

python之網路程式設計1-socket-tcp與udp

一、概念

兩個獨立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()

參考自https://www.cnblogs.com/Eva-J/p/5045061.html