1. 程式人生 > >TCP UDP粘包和程序部分

TCP UDP粘包和程序部分

TCP 半連線池原理

#客戶端
import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect(("127.0.0.1",9999))

while True:
        data = input(">>>:")
        if not data:continue
        client.send(data.encode("utf-8"))
        msg = client.recv(1024).decode("utf-8")
        print(msg)

client.close()

#伺服器
import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind(("127.0.0.1",9999))
#  不是最大連線數  !!
server.listen(5)

while True:
    c,addr = server.accept()
    while True:
        try:
            msg = c.recv(1024).decode("utf-8")
            if not msg:
                c.close()
                break
            c.send(msg.upper().encode("utf-8"))
        except BaseException:
            print("客戶端異常斷開")
            c.close()
            break
server.close()


UDP通訊

#客戶端
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # datagram資料報的意思

while True:
    msg = input(">>>:")
    client.sendto(msg.encode("utf-8"),("127.0.0.1",8888))
    data,addr = client.recvfrom(1024)
    print(data.decode("utf-8"))

#伺服器
import socket

# 建立socket物件  指定type引數為socket.SOCK_DGRAM 表示使用UDP協議
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # datagram資料報的意思
# 繫結ip和埠
server.bind(("127.0.0.1",8888))

while True:
    # 接收資料 返回一個元祖  資料和 傳送方的地址
    msg,c_addr = server.recvfrom(1024)
    print("收到來自%s: 說:%s" % (c_addr[0] ,msg.decode("utf-8")))
    # 傳送資料到指定ip和埠
    server.sendto(msg.upper(),c_addr)


UDP聊天

#客戶端
import socket

c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    msg = input(">>>:")
    c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))
    msg, addr = c.recvfrom(1024)
    print(msg.decode("utf-8"))

#伺服器
"""
    群聊思路
        1.客戶端先把資料交給伺服器
        2.伺服器先儲存對方的地址
        3.把收到的資料給所有人都發一遍

"""


import socket

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

server.bind(("127.0.0.1",8848))


# 如果客戶端與伺服器在同一臺計算機  並且有多個客戶端  這些客戶端ip都是相同的127.0.01

clients = {}

while True:
    msg,addr = server.recvfrom(1024)

    # 儲存對方的地址:
    clients[addr[1]] = addr

    print(msg.decode("utf-8"))
    # 迴圈發給所有人
    for c in clients:
        # 這個訊息不用給傳送方發回去
        # if c == addr[1]:
        #     continue
        server.sendto(msg,clients[c])

UDP聊天2

#傳送機
import socket

c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    msg = input(">>>:")
    c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))

#接收機
import socket

c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 先隨便發一條訊息給伺服器  讓服務知道自己的地址
c.sendto("register".encode("utf-8"),("127.0.0.1",8848))

while True:
    msg, addr = c.recvfrom(1024)
    print(msg.decode("utf-8"))

#伺服器
"""
    群聊思路
        1.客戶端先把資料交給伺服器
        2.伺服器先儲存對方的地址
        3.把收到的資料給所有人都發一遍

"""


import socket

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

server.bind(("127.0.0.1",8848))


# 如果客戶端與伺服器在同一臺計算機  並且有多個客戶端  這些客戶端ip都是相同的127.0.01

clients = {}

while True:
    msg,addr = server.recvfrom(1024)

    # 儲存對方的地址:
    clients[addr[1]] = addr

    print(msg.decode("utf-8"))
    # 迴圈發給所有人
    for c in clients:
        # 這個訊息不用給傳送方發回去
        # if c == addr[1]:
        #     continue
        server.sendto(msg,clients[c])

UDP會粘包嗎?

1.UDP 不會粘包 2.緩衝區大小要足夠裝資料包大小 建議不要超過512

UDP的使用場景: 視訊電話 語音電話 直播

DNS 域名解析伺服器

#客戶端
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # datagram資料報的意思
client.sendto("10".encode("utf-8"),("127.0.0.1",8888))
client.sendto("22".encode("utf-8"),("127.0.0.1",8888))
client.sendto("32".encode("utf-8"),("127.0.0.1",8888))
client.sendto("43".encode("utf-8"),("127.0.0.1",8888))


# while True:
    # msg = input(">>>:")
    # client.sendto(msg.encode("utf-8"),("127.0.0.1",8888))
    # data,addr = client.recvfrom(1024)
    # print(data.decode("utf-8"))

#伺服器
import socket

# 建立socket物件  指定type引數為socket.SOCK_DGRAM 表示使用UDP協議
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # datagram資料報的意思
# 繫結ip和埠
server.bind(("127.0.0.1",8888))

while True:
    # 接收資料 返回一個元祖  資料和 傳送方的地址
    msg,c_addr = server.recvfrom(512)
    print("收到來自%s: 說:%s" % (c_addr[0] ,msg.decode("utf-8")))
    # 傳送資料到指定ip和埠
    server.sendto(msg.upper(),c_addr)


UDP總結

1.TCP模板程式碼 半連線池的工作原理 目前我們的程式是單執行緒 伺服器要麼處理通訊要麼處理連線請求 無法同時進行

2.TCP 和 UDP 傳送資料時的流程 ***** 解釋 為何TCP是可靠的 是因為傳送資料後必須收到確認包

  1. UDP的模板程式碼 ***** 與TCP程式碼的區別 不需要監聽 不需要接收 type引數為 SOCK_DGRAM UDP 可以同時處理多個客戶端 是因為CPU處理速度快 給人感覺像是同時處理

什麼是程序

什麼是程序 正在進行(執行)的程式 在只有一個CPU的情況下 是因為有多道技術 記憶體被分為多個區域 存放不同的應用程式 當一個應用程式遇到了I/O操作時 作業系統會將CPU分配給其他的應用程式使用 切換的時間非常短 使用者是感覺不到的 特點: 一個作業系統中可以同時存在多個程序 內部使用了多道技術 可以快速在不同程序間切換 給使用者的感覺像是同時執行 程序是一個包含程式執行所需的所有資源的單位