1. 程式人生 > >python高階(一)——網路程式設計Socket(1)

python高階(一)——網路程式設計Socket(1)

一、UDP

1. 建立socket

在 Python 中 使用socket 模組的函式 socket 就可以完成:

import socket
socket.socket(AddressFamily, Type)

說明:

函式 socket.socket 建立一個 socket,該函式帶有兩個引數:

  • Address Family:可以選擇 AF_INET(用於 Internet 程序間通訊) 或者 AF_UNIX(用於同一臺機器程序間通訊),實際工作中常用AF_INET
  • Type:套接字型別,可以是 SOCK_STREAM(流式套接字,主要用於 TCP 協議)或者 SOCK_DGRAM(資料報套接字,主要用於 UDP 協議)

建立一個tcp socket(tcp套接字)

import socket

# 建立tcp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# ...這裡是使用套接字的功能(省略)...

# 不用的時候,關閉套接字
s.close()

建立一個udp socket(udp套接字)

import socket

# 建立udp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# ...這裡是使用套接字的功能(省略)...

# 不用的時候,關閉套接字
s.close()

說明

  • 套接字使用流程 與 檔案的使用流程很類似
    1. 建立套接字
    2. 使用套接字收/發資料
    3. 關閉套接字
#coding=utf-8

from socket import *

# 1. 建立udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2. 準備接收方的地址
# '192.168.1.103'表示目的ip地址
# 8080表示目的埠
dest_addr = ('192.168.1.103', 8080)  # 注意 是元組,ip是字串,埠是數字

# 3. 從鍵盤獲取資料
send_data = input("請輸入要傳送的資料:")

# 4. 傳送資料到指定的電腦上的指定程式中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)

# 5. 關閉套接字
udp_socket.close()

2. udp網路程式-傳送、接收資料

#coding=utf-8

from socket import *

# 1. 建立udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2. 準備接收方的地址
dest_addr = ('192.168.236.129', 8080)

# 3. 從鍵盤獲取資料
send_data = input("請輸入要傳送的資料:")

# 4. 傳送資料到指定的電腦上
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)

# 5. 等待接收對方傳送的資料
recv_data = udp_socket.recvfrom(1024)  # 1024表示本次接收的最大位元組數

# 6. 顯示對方傳送的資料
# 接收到的資料recv_data是一個元組
# 第1個元素是對方傳送的資料
# 第2個元素是對方的ip和埠
print(recv_data[0].decode('gbk'))
print(recv_data[1])

# 7. 關閉套接字
udp_socket.close()

3、埠繫結

 

#coding=utf-8

from socket import *

# 1. 建立套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2. 繫結本地的相關資訊,如果一個網路程式不繫結,則系統會隨機分配
local_addr = ('', 7788) #  ip地址和埠號,ip一般不用寫,表示本機的任何一個ip
udp_socket.bind(local_addr)

# 3. 等待接收對方傳送的資料
recv_data = udp_socket.recvfrom(1024) #  1024表示本次接收的最大位元組數

# 4. 顯示接收到的資料
print(recv_data[0].decode('gbk'))

# 5. 關閉套接字
udp_socket.close()

4、程式碼

import socket


# 目標IP、埠
DEST_IP = "192.168.1.1"
DEST_PORT = 8080


def send():
    # 建立udp的套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    while True:
        # 從鍵盤獲取資料
        send_data = input("請輸入要傳送的資料:")
        # 如果輸入的資料是exit,退出程式
        if send_data == "exit":
            break
        # 使用套接字的功能
        udp_socket.sendto(send_data.encode("utf-8"), (DEST_IP, DEST_PORT))
        # 不用的時候,關閉套接字
        udp_socket.close()


def recive():
    # 建立udp的套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 繫結一個本地資訊
    localaddr = ("", 7788)
    udp_socket.bind(localaddr)
    # 接收資料
    while True:
        recv_data = udp_socket.recvfrom(1024)
        # recv_data儲存的是一個元組(接收到的資料,(傳送方的ip,port))
        recv_msg = recv_data[0]  # 儲存接收的資料
        send_addr = recv_data[1]  # 儲存傳送方的地址資訊
        # 列印收到的資料
        # print(recv_data)
        print("%s:%s" % (str(send_addr), recv_msg.decode("gbk")))

    udp_socket.close()


if __name__ == '__main__':
    # send()
    recive()

二、TCP

1、tcp客戶端

tcp客戶端,並不是像之前一個段子:一個顧客去飯館吃飯,這個顧客要點菜,就問服務員咱們飯店有客戶端麼,然後這個服務員非常客氣的說道:先生 我們飯店不用客戶端,我們直接送到您的餐桌上

如果,不學習網路的知識是不是 說不定也會發生那樣的笑話 ,哈哈

所謂的伺服器端:就是提供服務的一方,而客戶端,就是需要被服務的一方

(1)tcp客戶端構建流程

tcp的客戶端要比伺服器端簡單很多,如果說伺服器端是需要自己買手機、查手機卡、設定鈴聲、等待別人打電話流程的話,那麼客戶端就只需要找一個電話亭,拿起電話撥打即可,流程要少很多

示例程式碼:

from socket import *

# 建立socket
tcp_client_socket = socket(AF_INET, 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()

(2)tcp同時服務多個客戶端

def server():
    # 建立socket
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 繫結本地資訊
    tcp_socket.bind("", 7890)
    # 預設套接字由主動變為被動
    tcp_socket.listen(128)

    while True:
        # 等待客戶端連線
        new_client_socket, client_addr = tcp_socket.accept()
        print(client_addr)
        while True:
            # 接收客戶端傳送來的請求
            recv_data = new_client_socket.recv(1024)
            print(recv_data)

            # 如果recv街阻塞,那麼有2種方式:
            # 1.客戶端傳送過來資料
            # 2.
            if recv_data:
                # 回送訊息
                new_client_socket.send("asdfa".encode("utf-8"))
            else:
                break
                # 關閉套接字
        new_client_socket.close()

    tcp_socket.close()