基於TCP協議的套接字編程

06.26自我總結

1.關於Socket

Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。python

socket模板已經爲咱們封裝好了,咱們只須要遵循socket的規定去編程,寫出的程序天然就是遵循tcp/udp標準的。編程

  • 注意:也有人將socket說成ip+port,ip是用來標識互聯網中的一臺主機的位置,而port是用來標識這臺機器上的一個應用程序,ip地址是配置到網卡上的,而port是應用程序開啓的,ip與port的綁定就標識了互聯網中獨一無二的一個應用程序,而程序的pid是同一臺機器上不一樣進程或者線程的標識。

2.套接字工做流程

3.套接字的函數

s都爲經過socket模塊生成設計模式

import socket

# socket_family 能夠是 AF_UNIX 或 AF_INET。socket_type 能夠是 SOCK_STREAM 或 SOCK_DGRAM。protocol 通常不填,默認值爲 0
socket.socket(socket_family, socket_type, protocal=0)

# 獲取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 獲取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 因爲 socket 模塊中有太多的屬性。咱們在這裏破例使用了'from module import *'語句。使用 'from socket import *',咱們就把 socket 模塊裏的全部屬性都帶到咱們的命名空間裏了,這樣能大幅減短咱們的代碼
s = socket(AF_INET, SOCK_STREAM)

1.服務器套接字函數

方法 用途
s.bind() 綁定(主機,端口號)到套接字 注:(127.0.0.1)表示本地ip
s.listen() 開始TCP監聽
s.accept() 被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來

2.客戶端套接字函數

方法 用途
s.connect() 主動初始化TCP服務器鏈接
s.connect_ex() connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常

3.公共用途的函數

方法 用途
s.recv() 接收TCP數據
s.send() 發送TCP數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
s.sendall() 發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)
s.recvfrom() 接收UDP數據
s.sendto() 發送UDP數據
s.getpeername() 鏈接到當前套接字的遠端的地址
s.getsockname() 當前套接字的地址
s.getsockopt() 返回指定套接字的參數
s.setsockopt() 設置指定套接字的參數
s.close() 關閉套接字

4.面向鎖套接字

方法 用途
s.setblocking() 設置套接字的阻塞與非阻塞模式
s.settimeout() 設置阻塞套接字操做的超時時間
s.gettimeout() 獲得阻塞套接字操做的超時時間

5.面向文件套接字

方法 用途
s.fileno() 套接字的文件描述符
s.makefile() 建立一個與該套接字相關的文件

4.示例

1.服務端

import socket

#一、買手機
phone = socket.socket(socket.AF_INET,
                      socket.SOCK_STREAM)  #tcp稱爲流式協議,udp稱爲數據報協議SOCK_DGRAM
# print(phone)

#二、插入/綁定手機卡
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1', 8080))

#三、開機
phone.listen(5)  # 半鏈接池,限制的是請求數

#四、等待電話鏈接
print('start....')
while True:  # 鏈接循環
    conn, client_addr = phone.accept()  #(三次握手創建的雙向鏈接,(客戶端的ip,端口))
    # print(conn)
    print('已經有一個鏈接創建成功', client_addr)

    #五、通訊:收\發消息
    while True:  # 通訊循環
        try:
            print('服務端正在收數據...')
            data = conn.recv(1024)  #最大接收的字節數,沒有數據會在原地一直等待收,即發送者發送的數據量必須>0bytes
            # print('===>')
            if len(data) == 0: break  #在客戶端單方面斷開鏈接,服務端纔會出現收空數據的狀況
            print('來自客戶端的數據', data)
            conn.send(data.upper())
        except ConnectionResetError:
            break
    #六、掛掉電話鏈接
    conn.close()

#七、關機
phone.close()

2.客戶端

import socket

#一、買手機
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# print(phone)
#二、撥電話
phone.connect(('127.0.0.1', 8080))  # 指定服務端ip和端口

#三、通訊:發\收消息
while True:  # 通訊循環
    msg = input('>>: ').strip()  #msg=''
    if len(msg) == 0: continue
    phone.send(msg.encode('utf-8'))
    # print('has send----->')
    data = phone.recv(1024)
    # print('has recv----->')
    print(data)

#四、關閉
phone.close()
相關文章
相關標籤/搜索