Python-socket編程筆記

HTTP\socket\TCP

請參考網絡模型,計算機給我們提供了socket,通過socket可以直接與傳輸層打交道

Socket編程的模式

在這裏插入圖片描述

client和server實現通信

首先是服務端

import socket

#  指明爲ipv4與tcp協議
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 必須傳入元組
server.bind(("0.0.0.0", 8000))
# 實現監聽
server.listen()
sock, addr = server.accept()

# 獲取從客戶端發送的數據,每次獲取1k的數據
data = sock.recv(1024)
# 將字節流轉碼爲utf-8編碼
print(data.decode("utf-8"))
sock.close()
server.close()

接着是客戶端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8000))
# 以字節輸出
client.send("Y4tacker".encode("utf-8"))
client.close()

這樣就實現了

socket實現聊天和多用戶連接

實現聊天

取消close方法即可,再加個while循環

服務端
while True:
    data = sock.recv(1024).decode("utf-8")
    print(data)
    ret_data = input("輸入回覆:")
    sock.send(ret_data.encode("utf-8"))
客戶端
while True:
    data = client.recv(1024)
    print(data.decode("utf-8"))
    ret_data = input("輸入回覆:")
    client.send(ret_data.encode("utf-8"))

利用線程實現多用戶的連接

服務端
import socket
import threading

#  指明爲ipv4與tcp協議
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 必須傳入元組
server.bind(("0.0.0.0", 8000))
# 實現監聽
server.listen()


def handle_sock(sock, addr):
    while True:
        data = sock.recv(1024).decode("utf-8")
        print(data)
        if "exit" == data:
            break
        ret_data = input()
        sock.send(ret_data.encode("utf-8"))
    sock.close()
    print("關閉連接")


while True:
    sock, addr = server.accept()
    # 用線程處理新的用戶連接
    client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
    client_thread.start()


客戶端
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8000))

while True:
    ret_data = input()
    client.send(ret_data.encode("utf-8"))
    data = client.recv(1024)
    print(data.decode("utf-8"))
    if "exit" == ret_data:
        print("關閉連接")
        break
client.close()


socket模擬http請求

爲了方便,利用urlparse來解析url

import socket
from urllib.parse import urlparse


def get_url(url):
    url = urlparse(url)
    # 以http://www.baidu.com/aa.html爲例
    # ParseResult(scheme='http', netloc='www.baidu.com', path='/aa.html', params='', query='', fragment='')
    host = url.netloc
    path = url.path
    if path == "":
        path = "/"
    # 建立socket連接
    con = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # HTTP都是80端口
    con.connect((host, 80))
    # 發送請求
    con.send(f'GET {path} HTTP/1.1\r\nHost:{host}\r\nConnection:close\r\n\r\n'.encode("utf-8"))
    # 接收請求,如果數據大於1024字節,則通過多次接收
    data = b""
    while True:
        temp = con.recv(1024)
        if temp:
            data += temp
        else:
            break
    data = data.decode("utf-8")
    # 去除請求頭
    html_data = data.split("\r\n\r\n")[1]
    print(html_data)
    con.close()


if __name__ == '__main__':
    url = "http://www.baidu.com"
    get_url(url)

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