中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

梅河口城鄉(xiāng)建設(shè)網(wǎng)站seo蜘蛛屯

梅河口城鄉(xiāng)建設(shè)網(wǎng)站,seo蜘蛛屯,wordpress采集csdn,重慶做石材的網(wǎng)站序言 在上一篇文章中,我們介紹了 協(xié)議,協(xié)議就是一種約定,規(guī)范了雙方通信需要遵循的規(guī)則、格式和流程,以確保信息能夠被準確地傳遞、接收和理解。 ?在這篇文章中我們將介紹怎么進行跨網(wǎng)絡(luò)數(shù)據(jù)傳輸,在這一過程中相信大家…

序言

?在上一篇文章中,我們介紹了 協(xié)議,協(xié)議就是一種約定,規(guī)范了雙方通信需要遵循的規(guī)則、格式和流程,以確保信息能夠被準確地傳遞、接收和理解。
?在這篇文章中我們將介紹怎么進行跨網(wǎng)絡(luò)數(shù)據(jù)傳輸,在這一過程中相信大家肯定可以加深對協(xié)議的理解。


端口號

1. 端口號的作用

?我們已經(jīng)理解了什么是 IPIP 用于標(biāo)識互聯(lián)網(wǎng)上的每個設(shè)備。我們可以通過他,將數(shù)據(jù)包能夠從一個設(shè)備跨網(wǎng)絡(luò)傳輸?shù)搅硪粋€設(shè)備。但是數(shù)據(jù)發(fā)送到設(shè)備上,還需要正確地被處理這才是目的吧!
?舉個栗子,大家平時也刷抖音吧!我們所看到的視頻就是抖音平臺所跨網(wǎng)絡(luò)傳輸給我們的數(shù)據(jù),但是有沒有可能我們手機在刷抖音的同時還有其他程序也正在運行。那么數(shù)據(jù)是怎么正確地被抖音所接受的而不是其他程序。
?每一個運行的程序以進程的方式存在于內(nèi)存中,所以抖音肯定也是。所以我們使用唯一的端口來標(biāo)識內(nèi)存中需要進行網(wǎng)絡(luò)傳輸?shù)倪M程,當(dāng)數(shù)據(jù)到達設(shè)備時就會根據(jù)端口號選擇進程

2. 再識端口號

?端口號存在于傳輸層協(xié)議層:

  • 端口號是一個 2 字節(jié) 16 位的整數(shù)
  • 端口號用來 標(biāo)識一個進程, 告訴操作系統(tǒng), 當(dāng)前的這個數(shù)據(jù)要交給哪一個進程來處理
  • IP 地址 + 端口號 能夠標(biāo)識網(wǎng)絡(luò)上的某一臺主機的某一個進程
  • 一個端口號只能被一個進程占用

第三點大家如何理解呢?一個 IP地址 標(biāo)識的是網(wǎng)絡(luò)是唯一的設(shè)備,而 端口號 標(biāo)識的是設(shè)備中唯一的一個進程,兩者一起就是標(biāo)識 網(wǎng)絡(luò)上的某一臺主機的某一個進程。
?所以實際上的網(wǎng)絡(luò)傳輸,不就是跨設(shè)備跨網(wǎng)絡(luò)的進程間通信嗎?

3. 端口號的需求

?服務(wù)端在運行時需要指定一個固定的端口號,這樣客戶端才能根據(jù)你的 IP地址,端口號 來找到需要進行通信的進程。但是端口號也不是隨便取的,是有要求的:

  • 0 - 1023: 知名端口號, HTTP, FTP, SSH 等這些廣為使用的應(yīng)用層協(xié)議, 他們的
    端口號都是固定的.
  • 1024 - 65535: 操作系統(tǒng)動態(tài)分配的端口號. 客戶端程序的端口號, 就是由操作
    系統(tǒng)從這個范圍分配的.

所以說我們只能在 1024 - 65535 進行選擇。

?客戶端就稍顯不同了,客戶端就不需要指定一個固定的端口號,這又是為什么呢?對于一個服務(wù)器來說,他的設(shè)備上只是運行了他的業(yè)務(wù)程序,而對于我們客戶端來說,我們的設(shè)備上可能同一時間運行著很多程序。如果每一個客戶端都固定一個端口的話,很 可能不同的客戶端之間就會造成沖突!所以為了避免這種情況,每次運行時操作系統(tǒng)都會為客戶端需要跨網(wǎng)絡(luò)通信的程序自動分配一個端口


簡單認識傳輸層協(xié)議

在傳輸層有很多協(xié)議(不同的傳輸方式),我們主要簡單介紹兩種 UDP, TCP ,在這里只是簡單介紹,在后面會詳細原理。

1. UDP 協(xié)議

?UDP協(xié)議 適用于 實時性要求較高、對數(shù)據(jù)可靠性 要求較低的應(yīng)用場景,如音頻、視頻傳輸(流媒體)、DNS解析、廣播和多播等:

  • UDP 是一種 無連接 的傳輸層協(xié)議,提供面向事務(wù)的簡單不可靠信息傳送服務(wù)。
  • 數(shù)據(jù)以數(shù)據(jù)報的形式獨立發(fā)送,不保證數(shù)據(jù)的可靠性、順序性和完整性。
  • UDP 協(xié)議開銷小,傳輸速度快,適用于對實時性要求較高、對數(shù)據(jù)可靠性要求較低的應(yīng)用場景。

2. TCP 協(xié)議

?TCP協(xié)議 適用于對數(shù)據(jù)完整性、順序性要求較高的應(yīng)用場景,如網(wǎng)頁瀏覽(HTTP)、文件傳輸(FTP)、郵件傳輸(SMTP)等:

  • TCP 是一種 面向連接的、可靠的、基于字節(jié)流 的傳輸層協(xié)議。
  • 在通信雙方之間建立一個虛擬的連接,然后在這個連接上進行數(shù)據(jù)的傳輸和控制。連接的建立和釋放需要經(jīng)過三次握手和四次揮手的過程。
  • 通過 序號、確認號、重傳機制、校驗 和等手段,保證數(shù)據(jù)在傳輸過程中不會出現(xiàn)丟失、重復(fù)、亂序或錯誤的情況。

3. 總結(jié)

?現(xiàn)在大家就需要簡單理解為 UDP 是不可靠的,數(shù)據(jù)傳輸可能會丟失部分信息,而 TCP 是可靠的,數(shù)據(jù)傳輸?shù)耐暾愿?。大家就會覺得,那我以后肯定選后后面的呀,因為他 可靠 嘛!不是這樣的,可靠也是需要代價的,需要你有穩(wěn)定且高速的網(wǎng)絡(luò)服務(wù)!
?協(xié)議的選擇要看具體的場景!就比如視頻的傳輸就最好選在前者, 所以你看視頻的時候偶爾會卡一下,但無關(guān)大雅!傳文件就選后者,因為你需要你的文件是完好的,文件如果傳過來丟失一部分數(shù)據(jù)那還怎么看!


網(wǎng)絡(luò)字節(jié)序

1. 什么是網(wǎng)絡(luò)字節(jié)序

?大家知道一個概念叫做 大小端 嗎?大端機是指將數(shù)據(jù)的高位存儲到內(nèi)存的低地址,而小端機是指將數(shù)據(jù)的低位存儲到地址的低地址:
在這里插入圖片描述

所以很可能你的設(shè)備是大端機,而需要接受數(shù)據(jù)的設(shè)備是小端機,為了解決這個問題提出了 網(wǎng)絡(luò)字節(jié)序

  • TCP/IP協(xié)議 規(guī)定,網(wǎng)絡(luò)數(shù)據(jù)流應(yīng)采用 大端字節(jié)序,即低地址高字節(jié).
  • 不管這臺主機是大端機還是小端機,都會按照這個TCP/IP規(guī)定的網(wǎng)絡(luò)字節(jié)序來發(fā)送 / 接收數(shù)據(jù)
  • 如果當(dāng)前發(fā)送主機是小端,就需要先將數(shù)據(jù)轉(zhuǎn)成大端;否則就忽略,直接發(fā)送即可

2. 相關(guān)接口

?當(dāng)然這個過程不需要我們自主實現(xiàn),已經(jīng)存在相應(yīng)的接口了:
在這里插入圖片描述
我們怎么來方便的記憶呢?h 代表 host(主機)n 代表 network(網(wǎng)絡(luò))l 代表 longs 代表 short。我們現(xiàn)在隨便選一個來解釋,就第三個吧:代表 網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)主機字節(jié)序,32位。


sockaddr 結(jié)構(gòu)

?該結(jié)構(gòu)體用于定義和存儲 IPv4地址 以及相關(guān)的端口信息:
在這里插入圖片描述

我們主要使用第二個結(jié)構(gòu)體,第三個是用于一個主機上的進程間通信,那第一個是干嘛的呢?這個結(jié)構(gòu)體本身只提供了一個非常基礎(chǔ)的框架,不能進行跨網(wǎng)絡(luò)通信或者是進程間通信,但他在底層 提供一個統(tǒng)一的接口,根據(jù)你第一個參數(shù)判斷你的通信類型。這不就是 C語言 的多態(tài)嗎?


UDP 網(wǎng)絡(luò)編程

?在這個版本我們將使用 UDP協(xié)議 來進行網(wǎng)絡(luò)編程,我們將實現(xiàn)一個客戶端用于發(fā)送信息,服務(wù)端用于接收消息:

1. Server 服務(wù)端

?首先我們需要指定,啟動程序時需要指定 IP 端口 :

int main(int argc, char* argvs[])
{if(argc != 3){std::cout << "Usage: ./server ip port" << std::endl;exit(1);}
}

我們根據(jù)相應(yīng)的內(nèi)容來初始化 struct sockaddr_in 結(jié)構(gòu)體的相關(guān)內(nèi)容:

// 初始化結(jié)構(gòu)體字段
struct sockaddr_in address;
address.sin_family = AF_INET; // 網(wǎng)絡(luò)通信
address.sin_addr.s_addr = inet_addr(IP.c_str()); // 將點分十進制的字符串改為長整型 127.0.0.1 => 0x7F000001
address.sin_port = htons(PORT); // 將端口號轉(zhuǎn)化位網(wǎng)絡(luò)字節(jié)序

之后我們創(chuàng)建套接字文件,我們的讀取和發(fā)送數(shù)據(jù)都需要經(jīng)過該文件:

// AF_INET 代表網(wǎng)絡(luò)通信
// SOCK_DGRAM 代表 UDP 協(xié)議
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{perror("socket:");
}

現(xiàn)在我們將套接字結(jié)構(gòu)體和文件綁定,代表該文件服務(wù)于指定端口:

// 綁定socket到端口 
int n = bind(sockfd, (struct sockaddr*)(&address), sizeof(address));
if(n < 0)
{perror("bind:");exit(0);
}

接收消息處理函數(shù)稍微有點長,但是思路是很簡單的:

// 不斷地接受客戶端的信息
char msg[1024];
struct sockaddr_in clientAddr;
socklen_t len = sizeof(clientAddr);
while(true)
{int n = recvfrom(sockfd, msg, sizeof(msg), 0, (struct sockaddr*)(&clientAddr), &len); // 接收消息if(n < 0){perror("recvfrom:");continue;}else if(n == 0){std::cout << "Client Quit..." << std::endl;exit(0);}msg[n] = '\0';printf("[%s:%s]# %s\n", inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port),msg);
}

首先我們定義一個緩沖區(qū) msg 接收返回值,之后通過 recvfrom 接受信息,之所以還需要傳入一個 clientAddr 的原因是因為,這是發(fā)送方的信息,你總得知道誰發(fā)給你打吧?之后我們有三種情況:

  • 接受失敗,返回 -1 。我們等待一下發(fā)送
  • 客戶端退出,返回 0 。我們也退出
  • 成功接收,返回發(fā)送的字符數(shù)

inet_ntoa 這個該函數(shù)是將 IP地址 轉(zhuǎn)化為我們熟悉的字符串形式,ntohs 將網(wǎng)絡(luò)字節(jié)序的端口號轉(zhuǎn)化為主機序列。

2. Client 客戶端

?客戶端有很多步驟是和服務(wù)端類似的,但是整體少簡單因為:

  • client 端口不需要用戶指定,OS 自動分配
  • client 不需要顯示的綁定自己的端口和 IP
  • 在首次向服務(wù)器發(fā)送信息時,會自動綁定

所以我們直接先通過參數(shù)獲取服務(wù)端的信息,并初始化對應(yīng)結(jié)構(gòu)體:

 if(argc != 3){std::cout << "Usage: ./server ip port" << std::endl;exit(1);}// 獲取 IPstd::string IP = argv[1];// 獲取端口號uint16_t PORT = std::stoi(argv[2]);// 初始化結(jié)構(gòu)體字段struct sockaddr_in address;address.sin_family = AF_INET; // 網(wǎng)絡(luò)通信address.sin_addr.s_addr = inet_addr(IP.c_str()); // 將點分十進制的字符串改為長整型 127.0.0.1 => 0x7F000001address.sin_port = htons(PORT); // 將端口號轉(zhuǎn)化位網(wǎng)絡(luò)字節(jié)序

現(xiàn)在我們還需要創(chuàng)建套接字文件:

 // AF_INET 代表網(wǎng)絡(luò)通信// SOCK_DGRAM 代表 UDP 協(xié)議int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd < 0){perror("socket:");}

我們客戶端不需要顯示綁定端口和 IP,現(xiàn)在可以直接構(gòu)造發(fā)送消息的邏輯:

// 不斷地向服務(wù)端發(fā)送信息
std::string msg;
while(true)
{std::cout << "Please Enter# ";std::cin >> msg;ssize_t n = sendto(sockfd, msg.c_str(), msg.size(), 0, (struct sockaddr*)(&address), sizeof(address));if(n < 0){perror("sendto:");continue;}
}

3. 總結(jié)

?其實很多時候服務(wù)端不需要指定 IP地址,因為一個設(shè)備可能有很多 IP地址,為了接受來自所有不同地址的請求,我們會設(shè)置:
address.sin_addr.s_addr = INADDR_ANY; 這代表接受所有 本設(shè)備 IP地址 的請求,處理數(shù)據(jù)。
?我們在之前提到過, UDP 是一種 無連接 的傳輸層協(xié)議。怎么體現(xiàn)呢?在這里我只是啟動客戶端程序,不啟動服務(wù)端,然后發(fā)送消息:
在這里插入圖片描述
可以看到即使是服務(wù)器不在線,我們依然能夠發(fā)送消息!


TCP 網(wǎng)絡(luò)編程

?我們將使用 TCP協(xié)議 來實現(xiàn)相同的功能:

1. Server 服務(wù)端

?前面的步驟都是一樣的,接受端口號,初始化結(jié)構(gòu)體字段,但是在創(chuàng)建套接字文件時,就需要更改一下選項了:

// SOCK_STREAM 代表 TCP 協(xié)議
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{perror("socket:");
}
std::cout << "Successful create sockfd..." << std::endl;

之后綁定也是一樣的,但是我們不能直接使用該套接字進行收發(fā)消息!該文件用于監(jiān)聽,查看是否有客戶端的請求:

// 監(jiān)聽,第二個參數(shù)大家先不管,后面理論會介紹
n = listen(sockfd, 3);
if(n < 0)
{perror("listen:");exit(1);
}
std::cout << "Successful listening..." << std::endl;

監(jiān)聽之后,當(dāng)有鏈接請求發(fā)送時,我們需要接受該請求,系統(tǒng)會返回一個進行數(shù)據(jù)讀寫的文件描述符:

// 連接
struct sockaddr_in ClientAddress; // 用于接收客戶端的信息
int newsockfd = accept(sockfd, (struct sockaddr*)(&ClientAddress), sizeof(ClientAddress));
if(newsockfd < 0)
{perror("connect:");exit(1);
}
std::cout << "Successful accept..." << std::endl;

之后便是接受信息哪些步驟:

// 不斷地接受客戶端的信息
char msg[1024];
while(true)
{int n = read(newsockfd, msg, sizeof(msg));if(n < 0){perror("read");continue;}else if(n == 0){std::cout << "Client Quit..." << std::endl;exit(0);}msg[n] = '\0';printf("[%s:%d]# %s\n", inet_ntoa(ClientAddress.sin_addr),ntohs(ClientAddress.sin_port),msg);
}

2. Client 客戶端

?客戶端的流程前面都一樣,獲取 IP地址,端口號,以及初始化結(jié)構(gòu)體字段,創(chuàng)建套接字文件,但是他需要一次連接請求:

// 連接請求
int n = connect(sockfd, (struct sockaddr*)(&address), sizeof(address));
if(n < 0)
{perror("connect:");exit(1);
}
std::cout << "Successful connect..." << std::endl;

當(dāng)連接成功時,就可以正常的通信了:

// 不斷地向服務(wù)端發(fā)送信息
std::string msg;
while(true)
{std::cout << "Please Enter# ";std::cin >> msg;ssize_t n = send(sockfd, msg.c_str(), msg.size(), 0);if(n < 0){perror("send:");continue;}
}

3. 總結(jié)

?TCP 是一種 面向連接的、可靠的、基于字節(jié)流 的傳輸層協(xié)議?,F(xiàn)在我們不啟動服務(wù)端,直接啟動客戶端發(fā)送消息:
在這里插入圖片描述
可以看到直接拒絕我們的連接,和 UDP 截然不同。


總結(jié)

?在這篇文章中我們介紹了在實踐上如何進行套接字編程,但是我們并沒有深入的理解理論的知識,希望大家有所收獲!

http://www.risenshineclean.com/news/58078.html

相關(guān)文章:

  • 專業(yè)網(wǎng)站開發(fā)服務(wù)線上推廣宣傳方式有哪些
  • 做3d動畫網(wǎng)站seo的主要工作是什么
  • 做二手房又做網(wǎng)站的如何制作一個網(wǎng)頁
  • 正規(guī)網(wǎng)站模板設(shè)計百度指數(shù)數(shù)據(jù)分析
  • wordpress 快訊功能seo免費自學(xué)的網(wǎng)站
  • 膠州建設(shè)信息網(wǎng)站百度搜索app免費下載
  • 龍巖紀檢委網(wǎng)站中國制造網(wǎng)網(wǎng)站類型
  • 網(wǎng)站的域名分為哪些網(wǎng)頁在線生成
  • 網(wǎng)站上傳后優(yōu)化大師apk
  • 溫州網(wǎng)站建設(shè)風(fēng)格網(wǎng)絡(luò)熱詞英語
  • 鄉(xiāng)鎮(zhèn)政府網(wǎng)站建設(shè)自查報告培訓(xùn)心得體會范文大全1000字
  • 移動網(wǎng)站是什么意思百度廣告聯(lián)盟一個月能賺多少
  • 網(wǎng)站建設(shè)費用包括哪些內(nèi)容優(yōu)化落實新十條措施
  • 網(wǎng)站推廣策劃的思路廈門網(wǎng)
  • 寶雞市市政工程建設(shè)管理處網(wǎng)站網(wǎng)站域名查詢ip地址
  • 免費搭建網(wǎng)站 優(yōu)幫云營銷網(wǎng)站建設(shè)軟件下載
  • 青島網(wǎng)站設(shè)計哪家便宜抖音廣告投放代理商
  • 重慶網(wǎng)上找工作哪個網(wǎng)站好十大騙子教育培訓(xùn)機構(gòu)
  • 天將建設(shè)集團有限公司網(wǎng)站企業(yè)網(wǎng)絡(luò)推廣最簡單方法
  • 做網(wǎng)站建設(shè)最好的公司是seo云優(yōu)化軟件
  • 如何做公司自己的網(wǎng)站首頁seo網(wǎng)站seo
  • 大連b2c網(wǎng)站建設(shè)如何建立網(wǎng)站服務(wù)器
  • 小程序網(wǎng)站開發(fā)運行合同網(wǎng)站建設(shè)技術(shù)外包
  • 國建設(shè)委員會網(wǎng)站上查詢搜索引擎優(yōu)化的完整過程
  • 福州電子商務(wù)網(wǎng)站在線識別圖片
  • 德州匯澤網(wǎng)站建設(shè)seo發(fā)貼軟件
  • 公司設(shè)計網(wǎng)站搜索引擎營銷的名詞解釋
  • 禮品網(wǎng)站制作免費推廣
  • 網(wǎng)站開發(fā) xmind營銷網(wǎng)站建設(shè)方案
  • 請問網(wǎng)上有沒有比較好的網(wǎng)站可以做照片書的呀?要求質(zhì)量比較好的!品牌推廣方案ppt