Python----網絡編程基礎 ---基於socket實現TCP協議與UDP協議的通信

網絡編程


Ubuntu命令
  查看ip:  ifconfig
   ping                                 查看網絡連通性
   ping 127.0.0.1                 檢查網絡功能是否正常
   ping 本機網卡IP地址       檢查網卡是否正常工作
   ping 遠程主機IP/域名      檢查與遠程主機的連通性


端口基礎
   定義:系統分配給網絡應用程序的編號,用來區分數據傳輸
   網絡程序必須要有端口號
   知名端口號0-1023
   動態端口號 1024-65535

檢驗指定端口網絡連接情況:netstat -an | grep ":8080"

列出當前系統端口所對應的程序:   lsof -i [tcp/udp]:8080

擴展: netstat -anp | grep  ":8080"      查看指定端口的程序網絡連接情況

擴展: ps -aux | grep  "python"           查看python的程序  

擴展:  kill -9 進程的PID                    關閉進程


 UDP

特點

  1.    無需確認對端是否存在,發送端隨時可發送數據
  2.    無連接、資源開銷小、速度塊、單個數據包最大爲64K
  3.    傳輸不可靠,容易丟失數據
  4.    沒有流量控制,所有接受方需及時接收數據,否則會出現緩衝過慢,電腦卡死

使用場景

  •    音樂視頻傳輸
  •    廣播
  •    主要用在通訊質量要求不高的場景

創建步驟

   客戶端:初始化,指定ip端口sendto發送,recvform接受,close關閉

#創建一個udp_licent
#初始化,ipv4,指定udp模式,綁定端口
#發送數據
#接受數據
#關閉套接字對象
import socket
import time

def main():
    #初始化
    udp_licent = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #發送數據
    udp_licent.sendto("要發送的數據".encode("utf-8"),('127.0.0.1',8080))
    #接受數據
    info = udp_licent.recvfrom(1024)  # 每次接受1024個字節數據
    print(info[0].decode("utf-8"))
    info = udp_licent.recvfrom(1024)   #每次接受1024個字節數據
    print(info[0].decode("utf-8"))  # 接受到的數據爲二進制數據進行解碼
    #關閉對象
    udp_licent.close()
    time.sleep(1)
if __name__ == '__main__':
    while True:
        main()


   服務端:初始化、端口複用、綁定端口、廣播模式、接受、發送(廣播模式255地址進行廣播)、關閉

#創建一個udp_server
#初始化
    #複用端口
    #綁定端口
    #設置廣播模式
#響應客戶端
    #接受數據
    #發送數據
#關閉套接字
import socket
def main():
    #初始化
    udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #複用端口
    udp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
    #設置廣播模式,發送時指定255.255.255.255
    udp_server.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,True)
    #綁定端口
    udp_server.bind(('',8080))
    #接受數據,收到數據爲一個元組,0下標元素爲數據,1號下標爲發送者地址與端口
    info = udp_server.recvfrom(1024)   #每次接受1024個字節數據
    #接受數據時阻塞程序
    print(".............程序被阻塞.................")
    #發送者地址信息
    news="收到:%s"%info[0].decode("utf-8")
    print(news)
    #發送數據,使用接受到的信息可以給發送者回復
    udp_server.sendto(news.encode("utf-8"),info[1])
    #使用255.255.255.255地址可以進行廣播發送,此時簡寫成發送者的端口
    #實際進行廣播時,客戶端要設置成與客戶端廣播一致的端口
    udp_server.sendto("進行廣播".encode("utf-8"),('255.255.255.255',info[1][1]))
    #關閉服務器套接字
    udp_server.close()

if __name__ == '__main__':
    while True:
        main()

 

TCP

概述

  •    面向連接的、可靠的、基於字節流的傳輸層通信協議.

特點

  1. TCP通信需要經過創建連接、數據傳送、終止連接三個步驟。
  2. 先建立連接纔可以進行數據傳輸,雙方都必須爲該連接分配必要的系統內核資源,以管理連接的狀態和連接上的傳輸可靠傳輸,採用發送應答機制,超時重傳,錯誤校驗,流量控制和阻塞管理

創建步驟

   客戶端:初始化、connect連接、send發送、recv接受,close關閉

import socket

# 創建tcp socket
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 目的信息
server_ip = input("請輸入服務器ip:")
server_port = int(input("請輸入服務器port:"))

# 鏈接服務器
tcp_client_socket.connect((server_ip, server_port))

# 提示用戶輸入數據
send_data = input("請輸入要發送的數據:")

tcp_client_socket.send(send_data.encode("gbk"))

# 接收對方發送過來的數據,最大接收1024個字節
recvData = tcp_client_socket.recv(1024)
print('接收到的數據爲:', recvData.decode('gbk'))

# 關閉套接字
tcp_client_socket.close()


   服務端:初始化、端口複用、綁定端口、監聽模式、建立連接生成服務對象、服務對象send發送、服務對象recv接受、關閉服務                      對象、關閉服務端

import socket

# 創建socket
tcp_server_socket = socket(socket.AF_INET, socket.SOCK_STREAM)

# 本地信息
address = ('', 7788)

# 綁定
tcp_server_socket.bind(address)


# 設置監聽
# 使用socket創建的套接字默認的屬性是主動的,使用listen將其變爲被動的,這樣就可以接收別人的鏈接了
# 128:表示最大等待連接數
tcp_server_socket.listen(128)

# 如果有新的客戶端來鏈接服務器,那麼就產生一個新的套接字專門爲這個客戶端服務
# client_socket用來爲這個客戶端服務
# tcp_server_socket就可以省下來專門等待其他新客戶端的鏈接
client_socket, clientAddr = tcp_server_socket.accept()

# 接收對方發送過來的數據
recv_data = client_socket.recv(1024)  # 接收1024個字節
print('接收到的數據爲:', recv_data.decode('gbk'))

# 發送一些數據到客戶端
client_socket.send("thank you !".encode('gbk'))

# 關閉爲這個客戶端服務的套接字,只要關閉了,就意味着爲不能再爲這個客戶端服務了,如果還需要服務,只能再次重新連接
client_socket.close()

 

UDP和TCP的區別

  1.   TCP面向連接不支持廣播,UDP不是面向連接支持廣播式
  2.   TCP需要連接,提供可靠數據傳輸且按序到達,但傳輸速度慢,UDP不需要連接,不保證可靠傳輸,但速度快
  3.   TCP適合發送大量數據,有流量控制,UDP適合發少量數據,沒有流量控制

文件下載器示例代碼

TCP服務端 參考代碼如下:
import socket
import os

if __name__ == '__main__':
    # 創建tcp服務端socket
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 設置socket選項,防止程序退出端口不立即釋放的問題
    tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 綁定端口
    tcp_serve_socket.bind(("", 9090))
    # 設置監聽,把主動套接字改成被動套接字,被動套接字只能接收客戶端的連接請求,不能收發消息
    tcp_serve_socket.listen(128)
    # 循環接收客戶端的連接請求, 提示:現在的下載是同步下載,一個用戶下載完成以後另外一個用戶才能下載
    while True:
        # 接收客戶端的連接請求
        service_client_socket, ip_port = tcp_serve_socket.accept()
        # 代碼執行到說明解阻塞,說明連接建立成功
        file_name_data = service_client_socket.recv(1024)
        # 解碼數據
        file_name = file_name_data.decode("gbk")
        print(file_name, ip_port)
        if os.path.exists(file_name):
            # 文件存在
            with open(file_name, "rb") as file:
                # 讀取文件數據
                while True:
                    file_data = file.read(1024)
                    if file_data:
                        # 發送文件數據給客戶端
                        service_client_socket.send(file_data)
                    else:
                        break
        else:
            print("文件不存在")
        # 終止和客戶端服務
        service_client_socket.close()
    # 終止提供處理連接請的服務
    tcp_serve_socket.close()
TCP客戶端 參考代碼如下:
import socket

if __name__ == '__main__':
    # 創建tcp客戶端socket
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立連接
    tcp_client_socket.connect(("192.168.107.160", 9090))
    # 獲取用戶輸入文件名
    file_name = input("請輸入您要下載的文件名:")
    # 使用gbk進行編碼
    file_name_data = file_name.encode("gbk")
    # 代碼執行到此,說明連接建立成功
    tcp_client_socket.send(file_name_data)
    with open("/home/python/Desktop/" + file_name, "wb") as file:
        # 循環接收服務端發送的文件二進制數據
        while True:
            # 獲取服務端文件數據
            file_data = tcp_client_socket.recv(1024)
            if file_data:
                # 寫入到指定文件
                file.write(file_data)
            else:
                break

    # 關閉socket
    tcp_client_socket.close()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章