網(wǎng)絡(luò)編程與TCP編程 理論基礎(chǔ)

一.網(wǎng)絡(luò)編程理論基礎(chǔ)

1.網(wǎng)絡(luò)

??????網(wǎng)絡(luò),顧名思義就是通過點(diǎn)、線、面組成的一張連通全球的虛擬的大網(wǎng),實(shí)現(xiàn)信息資源上的共享。

??????最早期的網(wǎng)絡(luò),是用物理線路將多臺計(jì)算機(jī)連接起來實(shí)現(xiàn)計(jì)算機(jī)之間特定的數(shù)據(jù)交互。這種方式一定程度上緩解了數(shù)據(jù)共享的需求。然而這種方式極為簡陋,極大的限制了數(shù)據(jù)共享的范圍和計(jì)算機(jī)共享的普遍適用性,越來越不能滿足日益發(fā)展的計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)的需求。

??????在這種迫切需求數(shù)據(jù)通信共享的情況下,計(jì)算機(jī)網(wǎng)絡(luò)計(jì)數(shù)有了飛速的發(fā)展,為了在眾多計(jì)算機(jī)中找到特定的計(jì)算機(jī),Vint cerf在實(shí)驗(yàn)?zāi)M階段使用了32位標(biāo)記的網(wǎng)絡(luò)地址協(xié)議(即后來的IP地址)用來標(biāo)識網(wǎng)絡(luò)上唯一的一臺計(jì)算機(jī),為了能在一臺計(jì)算機(jī)中找到特定的某個程序,將計(jì)算機(jī)中的每個和外界連接的數(shù)據(jù)程序設(shè)定了數(shù)據(jù)通信通道(即后來的端口)

??????同一時間國際標(biāo)準(zhǔn)化組織ISO定義了經(jīng)典的OSI/RM參考模型,極大的方便了人們在網(wǎng)絡(luò)上進(jìn)行數(shù)據(jù)通信傳輸,同時人們可以通過不同的協(xié)議進(jìn)行數(shù)據(jù)的有效傳播和共享

2.網(wǎng)絡(luò)編程的模型

??????每一個網(wǎng)絡(luò)應(yīng)用基本都由服務(wù)端和客戶端組成,網(wǎng)絡(luò)編程的模型也就是"客戶端-服務(wù)器端"模型。那么什么是服務(wù)端什么又是客戶端呢?見名知意,服務(wù)端負(fù)責(zé)管理某些資源,而客戶端就是這些資源的需求者。就如同售貨員跟顧客一樣,售貨員提供商品,客戶從售貨員這里獲得他們需要的物品。

客戶端-服務(wù)器端


3.網(wǎng)絡(luò)協(xié)議

??????什么是協(xié)議?協(xié)議呢,通俗的來講,網(wǎng)絡(luò)協(xié)議就是一種雙方都知道的必須遵守的約定。就比如兩個民族的人交流,但是你用苗語,他用瑤語,雖然各自都知道自己要表達(dá)的意思,但是對方聽不懂啊,為了更加友好的交流,就有了這么一個約定,都用漢語中的普通話交流,這樣就能消除各民族語言之間的差異導(dǎo)致的無效交流了,畢竟CCTV這個各民族都會看的頻道都說的是普通話嘛,誰都會誰都能聽得懂,何樂而不為呢?同樣的,計(jì)算機(jī)之間的通信也是遵循不同層次的協(xié)議,來實(shí)現(xiàn)計(jì)算機(jī)的通信。為了把全世界的所有不同類型的計(jì)算機(jī)都連接起來,就必須規(guī)定一套全球通用的協(xié)議,為了實(shí)現(xiàn)這個目標(biāo),互聯(lián)網(wǎng)協(xié)議簇就成為了通用協(xié)議標(biāo)準(zhǔn)。互聯(lián)網(wǎng)協(xié)議包含了上百種協(xié)議,但是最重要的兩個協(xié)議是TCP和IP協(xié)議,而我們通常把基于TCP和IP協(xié)議的所有協(xié)議統(tǒng)稱為”TCP/IP協(xié)議(蔟)”。

??????網(wǎng)絡(luò)協(xié)議又是用來干什么的呢?你用兩個不同主機(jī)之間需要進(jìn)行通信,需要利用各種硬件(光纖,路由器,交換機(jī)等)實(shí)現(xiàn)物理連接組成局域網(wǎng)和廣域網(wǎng).這些網(wǎng)絡(luò)中的主機(jī)如果需要進(jìn)行通信,就需要遵守相同的約定,即協(xié)議.網(wǎng)絡(luò)中的應(yīng)用抽象成7層,各層都有對應(yīng)的協(xié)議,這些協(xié)議有兩種基本的功能即命名方法(確定通信的雙方的身份)和傳送機(jī)制(如何把信息傳送過去).

七層模型


4.網(wǎng)絡(luò)中的通信方式

??????在網(wǎng)絡(luò)中,如何將數(shù)據(jù)包發(fā)送給對方呢?socket套接字的出現(xiàn)解決了這一問題,通過套接字 socket 對象的連接,完成多種協(xié)議的網(wǎng)絡(luò)程序服務(wù)端/客戶端的開發(fā)和數(shù)據(jù)通信。它不是一種協(xié)議,而是對TCP/UDP等協(xié)議進(jìn)行封裝以后供程序調(diào)用的接口,代碼中調(diào)用相應(yīng)的接口,即可將數(shù)據(jù)發(fā)送給對方。這種編程方式叫做socket編程.客戶端建立一個socket,服務(wù)端建立一個socket,二者建立連接后便可以進(jìn)行通信,以TCP協(xié)議的socket為例,步驟如下:

1)服務(wù)端創(chuàng)建一個socket,并且需要指定相應(yīng)的端口(端口為2字節(jié)),此時這個服務(wù)進(jìn)程便于該端口綁定,監(jiān)聽端口的連接請求;

2)客戶端創(chuàng)建一個socket,客戶端的端口號一般由內(nèi)核分配,

3)客戶端的socket向某IP地址:端口的socket發(fā)送連接請求;

4)服務(wù)端的socket監(jiān)聽到連接請求后建立連接,此時兩個socket便建立了可靠地TCP連接,可以進(jìn)行通信;

5)通信結(jié)束后客戶端關(guān)閉socket并向服務(wù)端發(fā)送關(guān)閉請求;

6)服務(wù)端受到關(guān)閉請求后關(guān)閉socket

socket是長連接,連接建立后可以多次通信,最后主動關(guān)閉連接.實(shí)際中可能長時間不通信socket也會斷掉,此時需要自己實(shí)現(xiàn)心跳機(jī)制確保連接不斷開;
??????基本語法結(jié)構(gòu):
socket.socket(socket_family, socket_type, protocal=0)
socket_family:socket 地址家族,AF_UNIX/AF_LOCAL 或者 AF_INET
socket_type:socket 連接類型
面向連接的(SOCK_STREAM),面向無連接的(SOCK_DGRAME)
protocal:傳輸協(xié)議,一般不用設(shè)置,使用默認(rèn)值進(jìn)行自動匹配就好
??????創(chuàng)建 TCP 協(xié)議的套接字 socket 對象:

tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

??????創(chuàng)建 UDP 協(xié)議的套接字 socket 對象:

udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

??????socket套接字常用操作:

屬性 描述
s.bind() 綁定(主機(jī)名稱、端口)到一個套接字上
s.listen() 設(shè)置并啟動TCP監(jiān)聽
s.accept() 等待客戶端連接
s.connect() 連接到指定服務(wù)器
s.connect_ex() 連接指定服務(wù)器。如果出現(xiàn)錯誤返回信息
s.recv() 接收TCP消息
s.recv_into() 接收TCP消息到緩沖區(qū)
s.send() 發(fā)送TCP消息
s.sendall() 完整發(fā)送TCP消息
s.recvfrom() 接收UDP消息
s.recvfrom_info() 接收UDP消息到緩沖區(qū)
s.sendto() 發(fā)送UDP消息
s.shutdown() 關(guān)閉連接對象
s.close() 關(guān)閉套接字對象


二.TCP編程理論基礎(chǔ)

1.三次握手與四次揮手

??????TCP是一種面向連接的,可靠的、基于字節(jié)流的傳輸層通信協(xié)議,通過三次握手與四次揮手完成連接的可靠性。
三次握手:
第一次握手:客戶端向服務(wù)器端發(fā)送連接請求包SYN(syn=j),等待服務(wù)器回應(yīng);

第二次握手:服務(wù)器端收到客戶端連接請求包SYN(syn=j)后,將客戶端的請求包SYN(syn=j)放入到自己的未連接隊(duì)列,此時服務(wù)器需要發(fā)送兩個包給客戶端;
 ?。?)向客戶端發(fā)送確認(rèn)自己收到其連接請求的確認(rèn)包ACK(ack=j+1),向客戶端表明已知道了其連接請求
 ?。?)向客戶端發(fā)送連接詢問請求包SYN(syn=k),詢問客戶端是否已經(jīng)準(zhǔn)備好建立連接,進(jìn)行數(shù)據(jù)通信;
  即在第二次握手時服務(wù)器向客戶端發(fā)送ACK(ack=j+1)和SYN(syn=k)包,此時服務(wù)器進(jìn)入SYN_RECV狀態(tài)。

第三次握手:客戶端收到服務(wù)器的ACK(ack=j+1)和SYN(syn=k)包后,知道了服務(wù)器同意建立連接,此時需要發(fā)送連接已建立的消息給服務(wù)器;
  向服務(wù)器發(fā)送連接建立的確認(rèn)包ACK(ack=k+1),回應(yīng)服務(wù)器的SYN(syn=k)告訴服務(wù)器,我們之間已經(jīng)建立了連接,可以進(jìn)行數(shù)據(jù)通信。
  ACK(ack=k+1)包發(fā)送完畢,服務(wù)器收到后,此時服務(wù)器與客戶端進(jìn)入ESTABLISHED狀態(tài),開始進(jìn)行數(shù)據(jù)傳送。

三次握手



四次揮手:
第一次揮手:主機(jī)A向主機(jī)B發(fā)送FIN包;A告訴B,我(A)發(fā)送給你(B)的數(shù)據(jù)大小是N,我發(fā)送完畢,請求斷開A->B的連接。

第二次揮手:主機(jī)B收到了A發(fā)送的FIN包,并向主機(jī)A發(fā)送ACK包;B回答A,是的,我總共收到了你發(fā)給我N大小的數(shù)據(jù),A->B的連接關(guān)閉。

第三次揮手:主機(jī)B向主機(jī)A發(fā)送FIN包;B告訴A,我(B)發(fā)送給你(A)的數(shù)據(jù)大小是M,我發(fā)送完畢,請求斷開B->A的連接。
第四次揮手:主機(jī)A收到了B發(fā)送的FIN包,并向主機(jī)B發(fā)送ACK包;A回答B(yǎng),是的,我收到了你發(fā)送給我的M大小的數(shù)據(jù),B->A的連接關(guān)閉。

四次揮手

2.服務(wù)端的開發(fā)

服務(wù)端的編程操作步驟如下:
1)定義需要監(jiān)聽的主機(jī) IP 和端口號
2)綁定 IP 地址和端口號到套接字對象
3)開始監(jiān)聽
4)等待連接
5)連接成功-開始數(shù)據(jù)通信
6) 斷開連接

# -*- coding: utf-8 -*-

import socket,time

HOST = ''
PORT = 8081
ADDRESS = (HOST,PORT)
BUFFER = 1024

#創(chuàng)建服務(wù)端套接字
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_server.bind(ADDRESS)
tcp_server.listen(10086)

while True:
    #等待客戶端建立連接
    print('waitting')
    client_socket,client_address = tcp_server.accept()
    print("歡迎{}的光臨".format(client_address))
    while True:
        #服務(wù)端發(fā)送消息
        info = input("server:")
        client_socket.send(info.encode('utf-8'))
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

        #接收客戶端消息
        msg = client_socket.recv(BUFFER)
        print("client{}:{}".format(client_address,msg.decode('utf-8')))
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        print("☆" * 20)

        #客戶端退出服務(wù)端等待狀態(tài)
        if msg == b'bye':
            client_socket.close()
            break

tcp_server.close()

3.客戶端的開發(fā)

客戶端開發(fā)操作步驟如下:
1)創(chuàng)建 TCP 連接套接字對象
2)向指定的 IP 和 PORT 發(fā)起請求,請求連接
3)連接成功,進(jìn)行數(shù)據(jù)收發(fā)操作
4)關(guān)閉連接,釋放資源

# -*- coding: utf-8 -*-

import socket,time

TARGET_HOST = '192.168.209.1'
TARGRT_PORT = 8081
TARGET_ADDRESS = (TARGET_HOST,TARGRT_PORT)
BUFFER = 1024

#創(chuàng)建套接字對象,連接主機(jī)
tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_client.connect(TARGET_ADDRESS)

while True:

    #接收服務(wù)端消息
    msg = tcp_client.recv(BUFFER)
    print("server:{}".format(msg.decode('utf-8')))
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

    #客戶端發(fā)送消息
    info = input("client:")
    tcp_client.send(info.encode('utf-8'))
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    print("☆" * 20)

    #客戶端關(guān)閉套接字退出
    if info == 'bye':
        tcp_client.close()
        break

print("客戶端退出")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、什么是TCP/IP 網(wǎng)絡(luò)和協(xié)議 1. TCP/IP是一類協(xié)議系統(tǒng),它是一套支持網(wǎng)絡(luò)通信的協(xié)議集合。網(wǎng)絡(luò)是計(jì)算機(jī)...
    karlon的馬甲閱讀 6,799評論 1 24
  • 網(wǎng)絡(luò)編程 網(wǎng)絡(luò)編程對于很多的初學(xué)者來說,都是很向往的一種編程技能,但是很多的初學(xué)者卻因?yàn)楹荛L一段時間無法進(jìn)入網(wǎng)絡(luò)編...
    程序員歐陽閱讀 2,105評論 1 37
  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(或多個)設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義,通過一定...
    蛋炒飯_By閱讀 1,369評論 0 10
  • 1、TCP為什么需要3次握手,4次斷開? “三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端...
    杰倫哎呦哎呦閱讀 3,662評論 0 6
  • 1.晚上9點(diǎn)21分地震了,11點(diǎn)3分boss問有沒那個團(tuán)隊(duì)的人在九寨溝,那里震感強(qiáng)烈。11點(diǎn)23分無人答復(fù),糾結(jié)了...
    同學(xué)愛米粒閱讀 167評論 0 0

友情鏈接更多精彩內(nèi)容