網路編程-SOCKET開發

来源:https://www.cnblogs.com/1oo88/archive/2019/05/04/10809485.html
-Advertisement-
Play Games

網路編程-SOCKET開發 網路編程架構分類 B/S架構 B指的是web(網頁),S指的是Server(服務端軟體) C/S架構 C指的是Client(客戶端軟體),S指的是Server(服務端軟體) OSI七層模型 OSI七層模型設計的目的 是成為一個所有電腦廠商都能實現的開放網路模型,來剋服使 ...


網路編程-SOCKET開發

網路編程架構分類

B/S架構

       B指的是web(網頁),S指的是Server(服務端軟體)

C/S架構

       C指的是Client(客戶端軟體),S指的是Server(服務端軟體)

OSI七層模型

OSI七層模型設計的目的

是成為一個所有電腦廠商都能實現的開放網路模型,來剋服使用眾多私有網路模型所帶來的困難和低效性。

TCP/IP五層模型:

     應用層(表示層、會話層)http協議

              大概是OS操作系統,系統軟體等用戶層面的。

     傳輸層(TCP/UDP協議、埠、四層路由器、四層交換機)

              建立埠到埠的通信,有兩種傳輸方式

              TCP協議:

                     TCP是全雙工的通信方式,可靠傳輸,速度慢,對傳遞的數據的長短沒有限制,只要不得到確認,就重新發送數據報,直到收到確認。

                     TCP的三次握手和四次揮手

 

 

SYN::同步標誌(請求連接)

ACK:確認標誌

FIN:結束標誌

              UDP協議:

                     UDP無需連接,不可靠,速度快,傳輸內容長度有限制。

     網路層(IP協議、路由器、三層交換機)

         IP協議

                     IP v4、IP v6

                     IP地址根據網路ID的不同分為五種類型,分別為A、B、C、D、E類地址

  1. A類:1.0.0.0-126.0.0.0
  2. B類:128.0.0.0-191.255.255.255
  3. C類:192.0.0.0-223.255.255.255
  4. D:用於多點廣播)
  5. E類:保留

*特殊:0.0.0.0-當前主機     255.255.255.255-當前子網的廣播地址       127.0.0.1-本機地址,又稱迴環地址。

     數據鏈路層(ARP協議、MAC地址相關、網卡、交換機)

              ARP協議:地址解析協議,確定目標物理地址

              MAC地址:機器唯一標識

     物理層(網線)

TCP/IP的傳輸(Socket)

       socket是應用層與TCP/IP協議族通信的中間軟體抽象層,相當於一組介面。引用此介面可以實現TCP連接。

socket server端實例代碼:

import socket        #導入socket介面

receive = socket.socket()
receive.bind(('127.0.0.1', 9999))    #此處的127.0.0.1為IP地址,9999為埠號
receive.listen()    #開始TCP監聽
conn, addr = receive.accept()    #被動接收TCP客戶端的連接,(阻塞)等待連接。
while True:
    conn.send('請輸入用戶名:'.encode('utf-8'))
    ret_user = conn.recv(1024).decode('utf-8')
    conn.send('請輸入密碼:'.encode('utf-8'))
    ret_psw = conn.recv(1024).decode('utf-8')
    if ret_user == 'zhao' and ret_psw == '123':
        conn.send('登錄成功'.encode('utf-8'))
        break
    else:
        conn.send('用戶名或密碼輸入錯誤'.encode('utf-8'))

conn.close()    #關閉套接字
receive.close()

 

socket client端實例代碼:

import socket

receive = socket.socket()
receive.connect(('127.0.0.1', 9999))    #連接IP地址為127.0.0.1,埠為9999的主機

while True:
    print(receive.recv(1024).decode('utf-8'))
    user = input('>>>')
    receive.send(user.encode('utf-8'))
    print(receive.recv(1024).decode('utf-8'))
    psw = input('>>>')
    receive.send(psw.encode('utf-8'))
    ret = receive.recv(1024).decode('utf-8')
    if ret == '登錄成功':
        print(ret)
        break
    else:
        print(ret)

receive.close()

 

公共用途的socket函數:

s.recv() 接收數據

s.send() 發送數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完,可後面通過實例解釋)

s.sendall() 發送完整的TCP數據(本質就是迴圈調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,迴圈調用send直到發完)

s.recvfrom() 收到的內容為 內容+IP地址

s.close() 關閉套接字

s.getpeername() 連接到當前套接字的遠端的地址

socket.setblocking(flag) #True or False,設置socket為非阻塞模式,以後講io非同步時會用

socket.getaddrinfo(host, port, family=0, type=0, proto=0,flags=0)返回遠程主機的地址信息

socket.getfqdn() 拿到本機的主機名

socket.gethostbyname() 通過功能變數名稱解析ip地址

黏包現象的解決

     黏包現象

              首先,黏包現象只出現在TCP傳輸中,由於某些原因經過TCP連續發送的信息在很短的時間內某個階段粘連在一起發送,接收方接收到的是一條消息。

     造成黏包的原因

1. 在發送端由於兩條消息發送的間隔時間很短,且兩條消息本身也很短,在發送之前被合成了一條消息。

2. 在接收端由於接收不及時導致兩條先後到達的信息在接收端黏在了一起。

黏包的本質

              信息與信息之間沒有邊界,且無法解決,因為TCP協議是流式傳輸。

解決黏包問題

              struct模塊:

                     把任意長度的數字變成固定的4個位元組。

l  簡單形式(先發送數據長度,再發送數據)

l  相對規範並複雜的形式(把所有想發送的數據信息放在字典里,發送字典長度,發送字典,發送數據)

struct模塊使用示例:

    發送:
    import struct
    ret=struct.pack(‘i’,10028)    #這裡的’i’代表將int型10028打包
    sk.send(ret)
    接收:
    num=sk.recv(4)
    num=struct.unpack(‘I’,ret)[0]    #這裡的’i’代表將ret中的內容解壓為int型,必須加[0],因為它傳過來的是元組。
    msg=conn.recv(num).decode(‘utf-8’)

 

UDP的傳輸

socket.SOCK_DGRAM #UDP傳輸

實例:

server端:

import socket

while True:
    receive = socket.socket(type=socket.SOCK_DGRAM)
    receive.bind(('0.0.0.0', 9999))
    while True:
        msg, addr = receive.recvfrom(1024)
        ret = msg.decode('utf-8')
        if ret.upper() == 'Q':
            receive.sendto(bytes('您已斷開連接!'.encode('utf-8')), addr)
            print('對方已與您斷開連接!')
            break
        elif ret == '您已斷開連接!':
            print(ret)
            break
        else:
            print(ret, addr)
        s = input('>>>').encode('utf-8')
        receive.sendto(bytes(s), addr)
receive.close()

 

client端:

import socket

receive = socket.socket(type=socket.SOCK_DGRAM)
while True:
    addr = input('輸入要連接的ip地址:')
    addr_port = int(input('輸入埠號:'))
    receive.connect((addr, addr_port))
    while True:
        n = input('>>>').encode('utf-8')
        receive.sendto(bytes(n), (addr, addr_port))
        msg = receive.recv(1024)
        ret = msg.decode('utf-8')
        if ret.upper() == 'Q':
            receive.sendto(bytes('您已斷開連接!'.encode('utf-8')), (addr, addr_port))
            print('對方已與您斷開連接!')
            break
        elif ret == '您已斷開連接!':
            print(ret)
            break
        else:
            print(ret)
receive.close()

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • golang 1.12 版本的自動補全問題 問題 golang 1.12 開始, 預設的 不再生成 pkg 文件. 所以對第三方庫的引用, 無法進行代碼的自動補全. 解決方法 會生成 pkg 文件夾和編譯文件 ...
  • java中的集合分成哪幾類? java中的集合常見面試題有哪些? java中的集合你不知道的那些事? ...
  • jupyter notebook的插件安裝及文本格式修改 1.jupyter notebook拓展插件安裝 啟動jupyter notebook : 打開控制台輸入命令 jupyter notebook 安裝Jupyter notebook extensions擴展插件: 1、pip install ...
  • Flask信號 信號是可以在固定的事件發生時執行某些事情 一個簡單的使用信號的例子: from flask import Flask,signals app = Flask(__name__) def signal_func(*args,**kwargs): print('信號') signals. ...
  • 題目鏈接 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this ...
  • 過去學C++語法都是用的這本C++Primer第五版 說實話,這本書應該是業界用的最多的一本類似於C++語法的百科全書了。。 但是感覺自己學了這麼長時間的C++,語法層次還是不夠牢固。 比如template的使用,多個類之間的組合關係.我個人使用的都不是十分熟練。 尤其是在看C++STL源碼刨析的時 ...
  • day21 02 包的進階 1._init_.py文件的操作 導入包 根據day21 01 包的初識,建立的glance包,直接import glance後通過“包點包。。點方法”是不能執行所要的方法的,必須通過在一層一層裡面的_init_.py或者其他類似的文件做相對應的導入操作,才可以運行以下代 ...
  • 半次元COS圖爬取-寫在前面 今天在瀏覽網站的時候,忽然一個莫名的鏈接指引著我跳轉到了半次元網站 https://bcy.net/ 打開之後,發現也沒有什麼有意思的內容,職業的敏感讓我瞬間聯想到了 cosplay ,這種網站必然會有這個的存在啊,於是乎,我準備好我的大爬蟲了。 把上面的鏈接打開之後, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...