Python全棧開發(fā)之網(wǎng)絡(luò)編程-創(chuàng)新互聯(lián)

No.1 TCP/IP

早期的計算機(jī)網(wǎng)絡(luò),都是由廠商規(guī)定自己的通信協(xié)議,互不兼容,為了把全世界不同類型的計算機(jī)連接起來,就必須規(guī)定一套全球通用的協(xié)議,所以就出現(xiàn)了TCP/IP
Python全棧開發(fā)之網(wǎng)絡(luò)編程

在潮南等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作按需網(wǎng)站策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計,成都全網(wǎng)營銷,成都外貿(mào)網(wǎng)站建設(shè),潮南網(wǎng)站建設(shè)費(fèi)用合理。

Python全棧開發(fā)之網(wǎng)絡(luò)編程

Python全棧開發(fā)之網(wǎng)絡(luò)編程

No.2 Socket簡介

要解決怎么標(biāo)識一個進(jìn)制,在一臺電腦上可以同pid標(biāo)識進(jìn)程,但是在網(wǎng)絡(luò)上是做不到的,其實(shí)TCP/IP就幫我們解決了這個問題,網(wǎng)絡(luò)層的IP可以標(biāo)識在網(wǎng)絡(luò)上的主機(jī),而傳輸層的協(xié)議+端口就可以標(biāo)識主機(jī)中

什么是Socket

socket是進(jìn)程通信的的一種方式,它與其他進(jìn)程通信的不同是,它能實(shí)現(xiàn)不同主機(jī)之間的進(jìn)程通信,我們網(wǎng)絡(luò)的應(yīng)用大多數(shù)都是采用這種方式進(jìn)行通信的

創(chuàng)建Socket

在Python中使用socket模塊

import socket
socket.socket(AddressFamily, Type)

函數(shù)socket可以創(chuàng)建一個socket對象,該函數(shù)存在兩個參數(shù)

Address Family:可以選擇 AF_INET(用于 Internet 進(jìn)程間通信) 或者 AF_UNIX(用于同一臺機(jī)器進(jìn)程間通信),實(shí)際工作中常用AF_INET

Type:套接字類型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 協(xié)議)或者 SOCK_DGRAM(數(shù)據(jù)報套接字,主要用于 UDP 協(xié)議)

創(chuàng)建一個tcp套接字

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.close()

創(chuàng)建一個udp套接字

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.close()

Socket函數(shù)

bind(address) 將套接字綁定到地址,在AF_INET下,以元祖(hsot,port)的形式表示地址
listen(backlog) 開始監(jiān)聽TCP傳入連接,backlog指定可以掛起的大連接數(shù)
accept() 接收TCP連接并返回(conn,address),其中conn是新的套接字對象,address是連接客戶端的地址
connect(address) 連接到address處的套接字,以元祖(hsot,port)的形式表示地址,連接出錯返回socket.error錯誤
connect_ex(address) 功能與s.connect(address) ,但是成功返回0,失敗返回errno的值
recv(bufsize[,flag]) 接收TCP套接字的數(shù)據(jù),數(shù)據(jù)以字節(jié)形式返回,bufsize指定接收的大數(shù)據(jù)量,flag提供有關(guān)消息的其他信息,通常可以忽略
send(string[,flag]) 發(fā)送TCP數(shù)據(jù),將string中的數(shù)據(jù)發(fā)送到連接的套接字,返回值是要發(fā)送的字節(jié)數(shù)量
sendall(string[],flag) 完整的發(fā)送TCP數(shù)據(jù),返回之前會嘗試發(fā)送所有數(shù)據(jù),成功返回Nonne,失敗拋出異常
recvfrom(bufsize[,flag]) 接收UDP套接字的數(shù)據(jù),與s.recv()類似,但返回值是(data,address),data表示接收的數(shù)據(jù),address表示發(fā)送數(shù)據(jù)的套接字地址
sendto(string[,flag],address) 發(fā)送UDP數(shù)據(jù),將數(shù)據(jù)發(fā)送到套接字,address是形式為(ipaddr,port)的元組,返回值是發(fā)送的字節(jié)數(shù)
close() 關(guān)閉套接字
getpeername() 返回連接套接字的遠(yuǎn)程地址,返回值是形式為(ipaddr,port)的元組
getsockname() 返回u套接字自己的地址,返回值是形式為(ipaddr,port)的元組
setsockopt(level,optname,value) 設(shè)置給定套接字選項的值
setsockopt(level,optname[.buflen]) 返回套接字選項的值
settimeout(timeout) 設(shè)置套接字及操作的朝時期,tiemout為一個浮點(diǎn)數(shù),單位是秒,值為None表示永遠(yuǎn)沒有朝時期
setblocking(flag) 如果flag為0,則將套接字設(shè)為非阻塞模式,非阻塞模式下,如果調(diào)用recv()沒有接收到任何數(shù)據(jù),或send()無法發(fā)送數(shù)據(jù),將引起socket.error異常

No.3 TCP的三次握手和四次揮手

Python全棧開發(fā)之網(wǎng)絡(luò)編程

Python全棧開發(fā)之網(wǎng)絡(luò)編程

No.4 TCP收發(fā)數(shù)據(jù)

客戶端

from socket import *

# 創(chuàng)建socket
tcp_client_socket = socket(AF_INET, SOCK_STREAM)
# 目的信息
server_ip = input("請輸入服務(wù)器ip:")
server_port = int(input("請輸入服務(wù)器port:"))
# 鏈接服務(wù)器
tcp_client_socket.connect((server_ip, server_port))
# 提示用戶輸入數(shù)據(jù)
send_data = input("請輸入要發(fā)送的數(shù)據(jù):")
tcp_client_socket.send(send_data.encode("gbk"))
# 接收對方發(fā)送過來的數(shù)據(jù),大接收1024個字節(jié)
recvData = tcp_client_socket.recv(1024)
print('接收到的數(shù)據(jù)為:', recvData.decode('gbk'))
# 關(guān)閉套接字
tcp_client_socket.close()

服務(wù)端

from socket import *

# 創(chuàng)建socket
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
# 綁定
tcp_server_socket.bind(('',9420))
# 使用socket創(chuàng)建的套接字默認(rèn)的屬性是主動的,使用listen將其變?yōu)楸粍拥?,這樣就可以接收別人的鏈接了
tcp_server_socket.listen(128)
# 等待連接,產(chǎn)生一個新的socket
client_socket, clientAddr = tcp_server_socket.accept()
# 接收對方發(fā)送過來的數(shù)據(jù)
recv_data = client_socket.recv(1024)  # 接收1024個字節(jié)
print('接收到的數(shù)據(jù)為:', recv_data.decode('gbk'))
# 發(fā)送一些數(shù)據(jù)到客戶端
client_socket.send("thank you !".encode('gbk'))
# 關(guān)閉套接字,只要關(guān)閉了,就意味著為不能再為這個客戶端服務(wù)了,如果還需要服務(wù),只能再次重新連接
client_socket.close()
tcp_server_socket.close()

No.5 TCP文件下載

客戶端

from socket import *

def main():
    tcp_client_socket = socket(AF_INET, SOCK_STREAM)
    server_ip = input("請輸入服務(wù)器ip:")
    server_port = int(input("請輸入服務(wù)器port:"))
    tcp_client_socket.connect((server_ip, server_port))
    file_name = input("請輸入要下載的文件名:")
    tcp_client_socket.send(file_name.encode("utf-8"))
    msg = ''
   while True:
        recv_data = tcp_client_socket.recv(1024)
        msg += recv_data.decode('utf-8')
        if len(recv_data) < 1024:
            break
    if msg:
       with open(file_name + 'bak', "w") as f:
            f.write(msg)

    tcp_client_socket.close()

if __name__ == "__main__":
    main()

服務(wù)端

from socket import *
import sys

def get_file_content(file_name):
    """獲取文件的內(nèi)容"""
    try:
       with open(file_name, "rb") as f:
            content = f.read()
        return content
    except:
        print("沒有下載的文件:%s" % file_name)

def main():
    tcp_server_socket = socket(AF_INET, SOCK_STREAM)
    tcp_server_socket.bind(('',9420))
    tcp_server_socket.listen(128)

   while True:
        client_socket, clientAddr = tcp_server_socket.accept()
        recv_data = client_socket.recv(1024)
        file_name = recv_data.decode("utf-8")
        print("對方請求下載的文件名為:%s" % file_name)
        file_content = get_file_content(file_name)
        if file_content:
            client_socket.send(file_content)
        client_socket.close()
    tcp_server_socket.close()

if __name__ == "__main__":
    main()

No.6 TCP的長連接和短連接

TCP長連接

client向server發(fā)起連接

server接收到請求,雙方建立連接

client向server發(fā)送消息

server回應(yīng)client

一次讀寫完畢,連接繼續(xù)

直到client發(fā)起關(guān)閉請求

TCP短連接

client向server發(fā)起連接

server接收到請求,雙方建立連接

client向server發(fā)送消息

server回應(yīng)client

一次讀寫完成,client發(fā)起斷開連接請求

TCP長/短連接的工作流程

長連接

Python全棧開發(fā)之網(wǎng)絡(luò)編程
短連接

Python全棧開發(fā)之網(wǎng)絡(luò)編程

TCP長/短連接的優(yōu)缺點(diǎn)

長連接可以省去較多的TCP創(chuàng)建和關(guān)閉的操作,減少浪費(fèi),節(jié)約時間,對于頻繁請求資源的場景來說,適合用長連接,但是隨著客戶端連接越來越多,server端早晚扛不住,這時候就需要采取一些策略,例如關(guān)閉一些長時間沒有讀取的連接,這樣可以避免惡意連接,還可以限制每個客戶端的最長連接數(shù),這樣可以避免某個客戶端拖后腿,短連接控制簡單,不需要控制手機(jī),但是如果客戶頻繁的請求資源,那就比較操蛋了,浪費(fèi)時間,浪費(fèi)帶寬

TCP長/短連接的適用場景

長連接適用于操作頻繁,點(diǎn)對點(diǎn)的的通訊,而且連接數(shù)不是太多的情況,每個TCP需要三次握手,如果每個操作都是先連接,再操作,會浪費(fèi)很長的時間,所以每個操作之后我們就不給它斷開,再次操作直接發(fā)送請求就可以了,例如,數(shù)據(jù)庫

像WEB網(wǎng)站的http服務(wù)一般采用短連接,因為長連接對服務(wù)器占用的資源太多,而且http服務(wù)的連接數(shù)一般不會太少,服務(wù)器難說能扛得住,所以并發(fā)量高的場景,最好采用短連接

No.7 UDP收發(fā)數(shù)據(jù)

from socket import *

udp_socket = socket(AF_INET, SOCK_DGRAM)
dest_addr = ('', 9420)
send_data = input("請輸入要發(fā)送的數(shù)據(jù):")
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
recv_data = udp_socket.recvfrom(1024) 
print(recv_data[0].decode('gbk'))
print(recv_data[1])
udp_socket.close()

No.8 UDP聊天室

import socket

def send_msg(udp_socket):
    msg = input("\n請輸入要發(fā)送的數(shù)據(jù):")
    dest_ip = input("\n請輸入對方的ip地址:")
    dest_port = int(input("\n請輸入對方的port:"))
    udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))

def recv_msg(udp_socket):
    recv_msg = udp_socket.recvfrom(1024)
    recv_ip = recv_msg[1]
    recv_msg = recv_msg[0].decode("utf-8")
    print(">>>%s:%s" % (str(recv_ip), recv_msg))

def main():
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.bind(("", 9420))
   while True:
        print("="*30)
        print("1:發(fā)送消息")
        print("2:接收消息")
        print("="*30)
        op_num = input("請輸入要操作的功能序號:")
        if op_num == "1":
            send_msg(udp_socket)
        elif op_num == "2":
            recv_msg(udp_socket)
        else:
            print("輸入有誤,請重新輸入...")

if __name__ == "__main__":
    main()

No.9 TCP和UDP

TCP特點(diǎn)

面向連接,通信雙方必須建立連接才能進(jìn)行數(shù)據(jù)的傳輸,雙方必須為對象分配必要的系統(tǒng)資源,TCP發(fā)送的每個報文段都必須得到接收方的應(yīng)答才認(rèn)為傳輸成功,發(fā)送端如果在規(guī)定時間內(nèi)沒有收到接收端的應(yīng)答,發(fā)送端會將報文段重新發(fā)送,TCP還會進(jìn)行數(shù)據(jù)校驗,還會通過流量控制機(jī)制避免主機(jī)發(fā)送太快而讓接收端接收不到數(shù)據(jù),完成數(shù)據(jù)交換后,通信雙方必須斷開連接,以釋放系統(tǒng)資源,這種連接是點(diǎn)對點(diǎn)的,因此TCP不適用廣播應(yīng)用程序

UDP特點(diǎn)

UDP并不提供對IP協(xié)議的可靠機(jī)制、流控制以及錯誤恢復(fù)功能等,由于UDP比較簡單, UDP頭包含很少的字節(jié),比 TCP 負(fù)載消耗少,UDP 適用于不需要 TCP 可靠機(jī)制的情形,QQ就是采用的UDP協(xié)議

通信模型

TCP

Python全棧開發(fā)之網(wǎng)絡(luò)編程

UDP

Python全棧開發(fā)之網(wǎng)絡(luò)編程

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

標(biāo)題名稱:Python全棧開發(fā)之網(wǎng)絡(luò)編程-創(chuàng)新互聯(lián)
本文來源:http://www.muchs.cn/article6/dhojog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、靜態(tài)網(wǎng)站網(wǎng)站排名、網(wǎng)站設(shè)計公司、網(wǎng)站維護(hù)、App設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)