4.1 socket

socket 

背景概念

 

腦圖結構

 

 

OSI 模型

 

 

 

socket 概念特性

腦圖結構

理解示意圖

 額外補充

  Socket是應用層與 TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。編程

  在設計模式中, Socket其實就是一個門面模式設計模式

  它把複雜的 TCP/IP協議族隱藏在 Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓 Socket去組織數據,以符合指定的協議。瀏覽器

 

 

 

TCP_socket

 

server

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8898))  # 把地址綁定到套接字
sk.listen()  # 監聽連接
conn,addr = sk.accept()  # 接受客戶端連接
ret = conn.recv(1024)  # 接收客戶端信息
print(ret)  # 打印客戶端信息
conn.send(b'hi')  # 向客戶端發送信息
conn.close()  # 關閉客戶端套接字
sk.close()  # 關閉服務器套接字(可選)

 

client

import socket
sk = socket.socket()  # 建立客戶套接字
sk.connect(('127.0.0.1',8898))  # 嘗試鏈接服務器
sk.send(b'hello!')
ret = sk.recv(1024)  # 對話(發送/接收)
print(ret)
sk.close()  # 關閉客戶套接字

 

 

特性

 

粘包

 

 

額外補充

  TCP (Transmission Control Protocol)可靠的、面向鏈接的協議(eg:打電話)、傳輸效率低全雙工通訊(發送緩存&接收緩存)、面向字節流。緩存

  使用TCP的應用:Web瀏覽器;電子郵件、文件傳輸程序。服務器

 

 

UDP_socket

 

 

 server

import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM)   #建立一個服務器的套接字
udp_sk.bind(('127.0.0.1',9000))        #綁定服務器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(b'hi',addr)                 # 對話(接收與發送)
udp_sk.close()                         # 關閉服務器套接字

 

client

import socket
ip_port=('127.0.0.1',9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b'hello',ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)

 

 

額外補充

  UDP (User Datagram Protocol)不可靠的、無鏈接的服務,傳輸效率高(發送前時延小),一對1、一對多、多對1、多對多、面向報文,盡最大努力服務,無擁塞控制。網絡

  使用UDP的應用:域名系統 (DNS);視頻流;IP語音(VoIP)。socket

 

其餘補充方法

 

 

 

文本筆記

socket概念
    套接字:實現網絡編程進行數據傳輸的一種技術手段
    相關模塊: import  socket
    分類
         流式套接字(SOCK_STREAM): 以字節流方式傳輸數據,實現tcp網絡傳輸方案。
         數據報套接字(SOCK_DGRAM):以數據報形式傳輸數據,實現udp網絡傳輸方案。

         面向鏈接--tcp協議--可靠的--流式套接字
         無鏈接--udp協議--不可靠--數據報套接字


tcp套接字編程
    服務端流程
        1. 建立套接字
            sk = socket.socket(socket_family=AF_INET,socket_type=SOCK_STREAM,proto=0)
            功能: 建立套接字
            參數:
                socket_family       網絡地址類型 AF_INET-->ipv4
                socket_type         選擇類型,與 TCP/UDP 中選擇, 默認就是 TCP 模式
                    套接字類型 SOCK_STREAM 流式(TCP)
                    SOCK_DGRAM 數據報(UDP)
                proto  一般爲0,能夠忽略       選擇子協議
            返回值: 套接字對象
        2. 綁定地址
            sk.bind(addr)
            功能: 綁定本機網絡地址
            參數: 二元元組 (ip,port)  例如:('0.0.0.0',8888)
        3. 設置監聽
            sk.listen(n)
            功能 : 將套接字設置爲監聽套接字,肯定監聽隊列大小
            參數 : 監聽隊列大小
        4. 等待處理客戶端鏈接請求
            conn,addr = sk.accept()
            功能: 阻塞等待處理客戶端請求
            返回值: conn  客戶端鏈接套接字
                     addr  鏈接的客戶端地址
            * 阻塞函數 : 程序運行過程當中遇到阻塞函數則暫停執行,直到達成某種條件後繼續運行。
        5. 消息收發
            data = conn.recv(buffersize)
                功能 : 接受客戶端消息
                參數 :每次最多接收消息的大小
                返回值: 接收到的內容

            n = conn.send(data)
                功能 : 發送消息
                參數 :要發送的內容  bytes格式
                返回值: 發送的字節數

            *  str --> bytes   string.encode()
               bytes --> str   bytes.decode()
        6. 關閉套接字
            sk.close()
            功能:關閉套接字
    """
    import socket
    sk = socket.socket()
    sk.bind(("127.0.0.1", 8008))
    sk.listen()
    conn, addr = sk.accept()
    conn.send(b"hello")
    conn.close()
    sk.close()
    """

    客戶端流程
        1. 建立套接字
            sk = socket.socket()
           * 只有相同類型的套接字才能進行通訊
        2. 請求鏈接
            sk.connect(server_addr)
                功能:鏈接服務器
                參數:元組  服務器地址
        3. 收發消息
            print(sk.recv(1024))
           * 防止兩端都阻塞,recv send要配合
        4. 關閉套接字
    """
    import socket
    sk = socket.socket()
    sk.connect(("127.0.0.1", 8008))
    print(sk.recv(1024))
    sk.close()
    """

    代碼流程總結
        服務端:socket() --> bind() --> listen() --> accept() --> recv(),send() --> close()
        客戶端:socket() --> connect() --> send(),recv() --> close()

    總體過程總結
        * tcp鏈接中當一端退出,另外一端若是阻塞在recv,此時recv會當即返回一個空字串。
        * tcp鏈接中若是一端已經不存在,讓然試圖經過send發送則會產生BrokenPipeError
        * 一個監聽套接字能夠同時鏈接多個客戶端,也可以重複被鏈接
        * 網絡收發緩衝區
            【1】網絡緩衝區有效的協調了消息的收發速度
            【2】send和recv實際是向緩衝區發送接收消息,當緩衝區不爲空recv就不會阻塞。
        * tcp粘包
            【1】 緣由:tcp以字節流方式傳輸,沒有消息邊界。屢次發送的消息被一次接收,此時就會造成粘包。
            【2】 影響:若是每次發送內容是一個獨立的含義,須要接收端獨立解析此時粘包會有影響。
            【3】 處理:
                1. 人爲的添加消息邊界
                2. 控制發送速度

UDP套接字編程
    服務端流程
        1. 建立數據報套接字
            sk = socket(AF_INET,SOCK_DGRAM)
        2. 綁定地址
            sk.bind(addr)
        3. 消息收發
            data,addr = sockfd.recvfrom(buffersize)
                功能: 接收UDP消息
                參數: 每次最多接收多少字節
                返回值: data  接收到的內容
                        addr  消息發送方地址
            n = sockfd.sendto(data,addr)
                功能: 發送UDP消息
                參數: data  發送的內容 bytes格式
                       addr  目標地址
                返回值:發送的字節數
        4. 關閉套接字
            sockfd.close()
    """
    import socket

    udp_sk = socket.socket(type=socket.SOCK_DGRAM)
    udp_sk.bind(('127.0.0.1', 9000))
    msg, addr = udp_sk.recvfrom(1024)
    print(msg)
    udp_sk.sendto(b'hi', addr)
    udp_sk.close()
    """

    客戶端流程
        1. 建立套接字
            sk=socket.socket(type=socket.SOCK_DGRAM)
        2. 收發消息
            sk.sendto(data,("127.0.0.1",8000))
            sk.recvfrom(1024)
        3. 關閉套接字
            sk.close()
    """
    import socket

    sk = socket.socket(type=socket.SOCK_DGRAM)
    addr = ("127.0.0.1", 9000)
    sk.sendto(b"hello", addr)
    data, addr = sk.recvfrom(1024)
    print(data)
    sk.close()
    """
相關文章
相關標籤/搜索