日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux心跳包C編程指南(linux心跳包c)

隨著現(xiàn)代網(wǎng)絡(luò)系統(tǒng)的不斷發(fā)展,網(wǎng)絡(luò)安全越來越成為企業(yè)、機構(gòu)和個人重要的關(guān)注點。為了更好地維護網(wǎng)絡(luò)環(huán)境安全,Linux系統(tǒng)給出了心跳包技術(shù)。在網(wǎng)絡(luò)連接過程中,如果設(shè)備出現(xiàn)故障,心跳包技術(shù)可以檢測出具體的設(shè)備,并及時通知管理員進行處理。

成都創(chuàng)新互聯(lián)公司專注于景縣網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供景縣營銷型網(wǎng)站建設(shè),景縣網(wǎng)站制作、景縣網(wǎng)頁設(shè)計、景縣網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造景縣網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供景縣網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

本文將為你介紹。

1. 心跳包的概念

心跳包技術(shù)利用持續(xù)發(fā)送的數(shù)據(jù)包測試網(wǎng)絡(luò)設(shè)備是否存活或處于聯(lián)網(wǎng)狀態(tài)。心跳數(shù)據(jù)包可以通過多種傳輸協(xié)議進行發(fā)送,如TCP、UDP等。

心跳包技術(shù)主要解決以下問題:

– 監(jiān)測網(wǎng)絡(luò)設(shè)備是否存活。

– 提供故障檢測和異常處理機制。

– 進行網(wǎng)絡(luò)流量控制。

2. Linux系統(tǒng)的心跳包

Linux內(nèi)核提供了一種心跳包實現(xiàn)機制。當(dāng)心跳包發(fā)送應(yīng)答時,系統(tǒng)會按照指定時間間隔生成心跳包數(shù)據(jù)并發(fā)送出去。如果在設(shè)定的時間內(nèi)沒有回應(yīng),系統(tǒng)會認(rèn)為網(wǎng)絡(luò)出現(xiàn)了問題,并進一步確認(rèn)損壞的設(shè)備或網(wǎng)絡(luò)節(jié)點。

同時,Linux系統(tǒng)還支持幾種心跳包協(xié)議。

2.1 ICMP協(xié)議

ICMP(Internet Control Message Protocol)協(xié)議是Linux系統(tǒng)默認(rèn)使用的協(xié)議。在進行ping測試時,就是通過ICMP協(xié)議生成相應(yīng)的心跳包。ICMP控制信息包常常用于網(wǎng)絡(luò)層和傳輸層之間的協(xié)議。

2.2 UDP協(xié)議

UDP(User Datagram Protocol)協(xié)議是一種無連接的協(xié)議,不保證可靠傳輸,但是在一些實時性要求較高的應(yīng)用場景下有更好的表現(xiàn)。

2.3 TCP協(xié)議

TCP(Tranission Control Protocol)協(xié)議是一種面向連接的協(xié)議,在進行可靠傳輸時更為可靠,但也更為復(fù)雜。TCP協(xié)議主要用于HTTP、FTP等協(xié)議的傳輸中。

3. 心跳包C語言實現(xiàn)

為了更好地實現(xiàn)心跳包檢測,我們可以使用C語言進行相關(guān)程序設(shè)計。

3.1 心跳包生成

生成心跳包的過程,通過設(shè)置發(fā)送方和接收方地址信息,以及具體的心跳包內(nèi)容來實現(xiàn)。

示例代碼:

“`

struct sockaddr_in dest_addr;

dest_addr.sin_family = AF_INET;

dest_addr.sin_port = htons(port);

dest_addr.sin_addr.s_addr = inet_addr(ip);

const char* data = “Hello world!”;

int data_len = strlen(data);

sendto(sockfd, data, data_len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));

“`

3.2 心跳監(jiān)測

接收方可以使用select或epoll等系統(tǒng)調(diào)用來實現(xiàn)心跳包的監(jiān)聽。這些系統(tǒng)調(diào)用可以同時監(jiān)聽多個套接字,有效提高系統(tǒng)處理效率。

示例代碼:

“`

// add sockfd to epoll

while (true) {

epoll_wt(epoll_fd, events, max_events, timeout);

for (int i = 0; i

int sockfd = events[i].data.fd;

memset(buf, 0, MAX_BUFFER_SIZE);

ssize_t recv_len = recvfrom(sockfd, buf, MAX_BUFFER_SIZE, 0, (struct sockaddr*)&addr, &addr_len);

// check if recv_buf is heartbeat data

}

}

“`

4.

通過本文,我們了解了心跳包的基本概念和Linux系統(tǒng)的心跳包實現(xiàn)機制。同時,我們還通過C語言代碼展示了如何實現(xiàn)心跳包的生成和監(jiān)測。

心跳包技術(shù)在網(wǎng)絡(luò)安全和網(wǎng)絡(luò)連接穩(wěn)定性方面都有重要的作用。希望本文能夠為大家提供一些參考和實踐的指導(dǎo)。

相關(guān)問題拓展閱讀:

  • 如何在linux環(huán)境下實現(xiàn)客戶端和服務(wù)器之間
  • 一篇搞懂tcp,http,socket,socket連接池之間的關(guān)系

如何在linux環(huán)境下實現(xiàn)客戶端和服務(wù)器之間

網(wǎng)絡(luò)的Socket數(shù)據(jù)傳輸是一種特殊的I/O,Socket也是一種文件描述符。Socket也具有一個類似于打開文件肆螞斗的函數(shù)調(diào)用Socket(),該函數(shù)返回一個整型的Socket描述符,隨后的連接建立、數(shù)據(jù)傳輸?shù)炔僮鞫际峭ㄟ^物喊該Socket實現(xiàn)的。

下面用Socket實現(xiàn)一個windows下的c語言socket通信例子,這里我們客戶端傳遞一個字裂磨符串,服務(wù)器端進行接收。

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

【服務(wù)器端】

#include “stdafx.h”

#include

#include

#include

#define SERVER_PORT 5208 //偵聽端口

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int ret, nLeft, length;

SOCKET sListen, sServer; //偵聽套接字,連接套接字

struct sockaddr_in saServer, saClient; //地址信息

char *ptr;//用于遍歷信息的指針

//WinSock初始化

wVersionRequested=MAKEWORD(2, 2); //希望使用的WinSock DLL 的版本

ret=WSAStartup(wVersionRequested, &wsaData);

if(ret!=0)

{

printf(“WSAStartup() failed!\n”);

return;

}

//創(chuàng)建Socket,使用TCP協(xié)議

sListen=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (sListen == INVALID_SOCKET)

{

WSACleanup();

printf(“socket() faild!\n”);

return;

}

//構(gòu)建本地地址信息

saServer.sin_family = AF_INET; //地址家族

saServer.sin_port = htons(SERVER_PORT); //注意轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序

saServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //使用INADDR_ANY 指示任意地址

//綁定

ret = bind(sListen, (struct sockaddr *)&saServer, sizeof(saServer));

if (ret == SOCKET_ERROR)

{

printf(“bind() faild! code:%d\n”, WSAGetLastError());

closesocket(sListen); //關(guān)閉套接字

WSACleanup();

return;

}

//偵聽連接請求

ret = listen(sListen, 5);

if (ret == SOCKET_ERROR)

{

printf(“l(fā)isten() faild! code:%d\n”, WSAGetLastError());

closesocket(sListen); //關(guān)閉套接字

return;

}

printf(“Waiting for client connecting!\n”);

printf(“Tips: Ctrl+c to quit!\n”);

//阻塞等待接受客戶端連接

while(1)//循環(huán)監(jiān)聽客戶端,永遠(yuǎn)不停止,所以,在本項目中,我們沒有心跳包。

{

length = sizeof(saClient);

sServer = accept(sListen, (struct sockaddr *)&saClient, &length);

if (sServer == INVALID_SOCKET)

{

printf(“accept() faild! code:%d\n”, WSAGetLastError());

closesocket(sListen); //關(guān)閉套接字

WSACleanup();

return;

}

char receiveMessage;

nLeft = sizeof(receiveMessage);

ptr = (char *)&receiveMessage;

while(nLeft>0)

{

//接收數(shù)據(jù)

ret = recv(sServer, ptr, 5000, 0);

if (ret == SOCKET_ERROR)

{

printf(“recv() failed!\n”);

return;

}

if (ret == 0) //客戶端已經(jīng)關(guān)閉連接

{

printf(“Client has closed the connection\n”);

break;

}

nLeft -= ret;

ptr += ret;

}

printf(“receive message:%s\n”, receiveMessage);//打印我們接收到的消息。

}

// closesocket(sListen);

// closesocket(sServer);

// WSACleanup();

}

【客戶端】

#include “stdafx.h”

#include

#include

#include

#define SERVER_PORT 5208 //偵聽端口

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int ret;

SOCKET sClient; //連接套接字

struct sockaddr_in saServer; //地址信息

char *ptr;

BOOL fSuccess = TRUE;

//WinSock初始化

wVersionRequested = MAKEWORD(2, 2); //希望使用的WinSock DLL的版本

ret = WSAStartup(wVersionRequested, &wsaData);

if(ret!=0)

{

printf(“WSAStartup() failed!\n”);

return;

}

//確認(rèn)WinSock DLL支持版本2.2

if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)

{

WSACleanup();

printf(“Invalid WinSock version!\n”);

return;

}

//創(chuàng)建Socket,使用TCP協(xié)議

sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (sClient == INVALID_SOCKET)

{

WSACleanup();

printf(“socket() failed!\n”);

return;

}

//構(gòu)建服務(wù)器地址信息

saServer.sin_family = AF_INET; //地址家族

saServer.sin_port = htons(SERVER_PORT); //注意轉(zhuǎn)化為網(wǎng)絡(luò)節(jié)序

saServer.sin_addr.S_un.S_addr = inet_addr(“192.168.1.127”);

//連接服務(wù)器

ret = connect(sClient, (struct sockaddr *)&saServer, sizeof(saServer));

if (ret == SOCKET_ERROR)

{

printf(“connect() failed!\n”);

closesocket(sClient); //關(guān)閉套接字

WSACleanup();

return;

}

char sendMessage=”hello this is client message!”;

ret = send (sClient, (char *)&sendMessage, sizeof(sendMessage), 0);

if (ret == SOCKET_ERROR)

{

printf(“send() failed!\n”);

}

else

printf(“client info has been sent!”);

closesocket(sClient); //關(guān)閉套接字

WSACleanup();

一篇搞懂tcp,http,socket,socket連接池之間的關(guān)系

作為一名開發(fā)人員我們經(jīng)常會聽到HTTP協(xié)議、TCP/IP協(xié)議、UDP協(xié)議、Socket、Socket長連接、Socket連接池等字眼,然而它們之間的關(guān)系、區(qū)別及原理并不是所有人都能理解清楚,這篇文章就從網(wǎng)絡(luò)協(xié)議基礎(chǔ)開始到Socket連接池,一步一步解釋他們之間的關(guān)系。

首先從網(wǎng)絡(luò)通信的分層模型講起:七層模型,亦稱OSI(Open System Interconnection)模型。自下往上分為:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會話層、表示層和應(yīng)用層。所有有關(guān)通信的都離不開它,下面這張圖片介紹了各層所對應(yīng)的一些協(xié)議和硬件

通過上圖,我知道IP協(xié)議對應(yīng)于網(wǎng)絡(luò)層,TCP、UDP協(xié)議對應(yīng)于傳輸層,而HTTP協(xié)議對應(yīng)于應(yīng)用層,OSI并沒有Socket,那什么是Socket,后面我們將結(jié)合代碼具體詳細(xì)介紹。

關(guān)于傳輸層TCP、UDP協(xié)議可能我們平時遇見的會比較多,有人說TCP是安全的,UDP是不安全的,UDP傳輸比TCP快,那為什么呢,我們先從TCP的連接建立的過程開始分析,然后解釋UDP和TCP的區(qū)別。

TCP的三次握手和四次分手

我們知道TCP建立連接需要經(jīng)過三次握手,而斷開連接需要經(jīng)過四次分手,那三次握手和四次分手分別做了什么和如何進行的。

之一次握手:

建立連接。客戶端發(fā)送連接請求報文段,將SYN位置為1,Sequence Number為x;然后,客戶端進入SYN_SEND狀態(tài),等待服務(wù)器的確認(rèn);

第二次握手:

服務(wù)器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認(rèn),設(shè)置Acknowledgment Number為x+1(Sequence Number+1);同時,明含自己自己還要發(fā)送SYN請求信息,將SYN位置為1,Sequence Number為y;服務(wù)器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一并發(fā)送給客戶端,此時服務(wù)器進入SYN_RECV狀態(tài);

第三次握手:

客戶端收到服務(wù)器的SYN+ACK報文段。然后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報文段,這個報文段發(fā)送完畢以后,客戶端和服務(wù)器端都進入ESTABLISHED狀態(tài),完成TCP三次握手。

完成了三次握手,客戶端和服務(wù)器端就可以開始傳送數(shù)據(jù)。以上就是TCP三次握手的總體介紹。通信結(jié)束客戶端和服務(wù)端就斷開連接,需要經(jīng)過四次分手確認(rèn)。

之一次分手:

主機1(可以使客戶端,也可以是服務(wù)器端),設(shè)置Sequence Number和Acknowledgment Number,向主機2發(fā)送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態(tài);這表示主機1沒有數(shù)據(jù)要發(fā)送給主機2了;

第二次分手:

主機2收到了主機1發(fā)送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態(tài);主機2告訴主機1,我“同意”你的關(guān)閉請求;

第三次分手:

主機2向主機1發(fā)送FIN報文段,請求關(guān)閉連接,同時主機2進入LAST_ACK狀態(tài);

第四次分手

:主機1收到主機2發(fā)送的FIN報文段,向主機2發(fā)送ACK報文段,然后主機1進入TIME_WAIT狀態(tài);主機2收到主機1的ACK報文段以后,就關(guān)閉連接;此時,主激橋笑機1等待2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,主機1也可以關(guān)閉連接了。

可以看到一次tcp請求的建立及關(guān)閉至少進行7次通信,這還不包過數(shù)據(jù)的通信,而UDP不需3次握手和4次分手。

TCP和UDP的區(qū)別

 1、TCP是面向鏈接的,雖然說網(wǎng)絡(luò)的不安全不穩(wěn)定特性決定了多少次握手都不能保證連接的可靠性,但TCP的三次握手在更低限度上(實際上也很大程度上保證了)保證了連接的消此可靠性;而UDP不是面向連接的,UDP傳送數(shù)據(jù)前并不與對方建立連接,對接收到的數(shù)據(jù)也不發(fā)送確認(rèn)信號,發(fā)送端不知道數(shù)據(jù)是否會正確接收,當(dāng)然也不用重發(fā),所以說UDP是無連接的、不可靠的一種數(shù)據(jù)傳輸協(xié)議?!?/p>

 2、也正由于1所說的特點,使得UDP的開銷更小數(shù)據(jù)傳輸速率更高,因為不必進行收發(fā)數(shù)據(jù)的確認(rèn),所以UDP的實時性更好。知道了TCP和UDP的區(qū)別,就不難理解為何采用TCP傳輸協(xié)議的MSN比采用UDP的QQ傳輸文件慢了,但并不能說QQ的通信是不安全的,因為程序員可以手動對UDP的數(shù)據(jù)收發(fā)進行驗證,比如發(fā)送方對每個數(shù)據(jù)包進行編號然后由接收方進行驗證啊什么的,即使是這樣,UDP因為在底層協(xié)議的封裝上沒有采用類似TCP的“三次握手”而實現(xiàn)了TCP所無法達(dá)到的傳輸效率。

關(guān)于傳輸層我們會經(jīng)常聽到一些問題

1.TCP服務(wù)器更大并發(fā)連接數(shù)是多少?

關(guān)于TCP服務(wù)器更大并發(fā)連接數(shù)有一種誤解就是“因為端口號上限為65535,所以TCP服務(wù)器理論上的可承載的更大并發(fā)連接數(shù)也是65535”。首先需要理解一條TCP連接的組成部分:

客戶端IP、客戶端端口、服務(wù)端IP、服務(wù)端端口

。所以對于TCP服務(wù)端進程來說,他可以同時連接的客戶端數(shù)量并不受限于可用端口號,理論上一個服務(wù)器的一個端口能建立的連接數(shù)是全球的IP數(shù)*每臺機器的端口數(shù)。實際并發(fā)連接數(shù)受限于linux可打開文件數(shù),這個數(shù)是可以配置的,可以非常大,所以實際上受限于系統(tǒng)性能。通過#ulimit -n 查看服務(wù)的更大文件句柄數(shù),通過ulimit -n xxx 修改 xxx是你想要能打開的數(shù)量。也可以通過修改系統(tǒng)參數(shù):

2.為什么TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)?

這是因為雖然雙方都同意關(guān)閉連接了,而且握手的4個報文也都協(xié)調(diào)和發(fā)送完畢,按理可以直接回到CLOSED狀態(tài)(就好比從SYN_SEND狀態(tài)到ESTABLISH狀態(tài)那樣);但是因為我們必須要假想網(wǎng)絡(luò)是不可靠的,你無法保證你最后發(fā)送的ACK報文會一定被對方收到,因此對方處于LAST_ACK狀態(tài)下的Socket可能會因為超時未收到ACK報文,而重發(fā)FIN報文,所以這個TIME_WAIT狀態(tài)的作用就是用來重發(fā)可能丟失的ACK報文。

3.TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)會產(chǎn)生什么問題

通信雙方建立TCP連接后,主動關(guān)閉連接的一方就會進入TIME_WAIT狀態(tài),TIME_WAIT狀態(tài)維持時間是兩個MSL時間長度,也就是在1-4分鐘,Windows操作系統(tǒng)就是4分鐘。進入TIME_WAIT狀態(tài)的一般情況下是客戶端,一個TIME_WAIT狀態(tài)的連接就占用了一個本地端口。一臺機器上端口號數(shù)量的上限是65536個,如果在同一臺機器上進行壓力測試模擬上萬的客戶請求,并且循環(huán)與服務(wù)端進行短連接通信,那么這臺機器將產(chǎn)生4000個左右的TIME_WAIT Socket,后續(xù)的短連接就會產(chǎn)生address already in use : connect的異常,如果使用Nginx作為方向代理也需要考慮TIME_WAIT狀態(tài),發(fā)現(xiàn)系統(tǒng)存在大量TIME_WAIT狀態(tài)的連接,通過調(diào)整內(nèi)核參數(shù)解決。

編輯文件,加入以下內(nèi)容:

然后執(zhí)行 /in/sysctl -p 讓參數(shù)生效。

net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當(dāng)出現(xiàn)SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊,默認(rèn)為0,表示關(guān)閉;

net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認(rèn)為0,表示關(guān)閉;

net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認(rèn)為0,表示關(guān)閉。

net.ipv4.tcp_fin_timeout 修改系統(tǒng)默認(rèn)的TIMEOUT時間

相關(guān)視頻推薦

10道網(wǎng)絡(luò)八股文,每道都很經(jīng)典,讓你在面試中逼格滿滿

徒手實現(xiàn)網(wǎng)絡(luò)協(xié)議棧,請準(zhǔn)備好環(huán)境,一起來寫代碼

學(xué)習(xí)視頻教程-騰訊課堂

需要C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料加qun獲?。ㄙY料包括

C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg

等),免費分享

關(guān)于TCP/IP和HTTP協(xié)議的關(guān)系,網(wǎng)絡(luò)有一段比較容易理解的介紹:“我們在傳輸數(shù)據(jù)時,可以只使用(傳輸層)TCP/IP協(xié)議,但是那樣的話,如果沒有應(yīng)用層,便無法識別數(shù)據(jù)內(nèi)容。如果想要使傳輸?shù)臄?shù)據(jù)有意義,則必須使用到應(yīng)用層協(xié)議。應(yīng)用層協(xié)議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應(yīng)用層協(xié)議。

HTTP協(xié)議即超文本傳送協(xié)議(Hypertext Transfer Protocol ),是Web聯(lián)網(wǎng)的基礎(chǔ),也是手機聯(lián)網(wǎng)常用的協(xié)議之一,WEB使用HTTP協(xié)議作應(yīng)用層協(xié)議,以封裝HTTP文本信息,然后使用TCP/IP做傳輸層協(xié)議將它發(fā)到網(wǎng)絡(luò)上。

由于HTTP在每次請求結(jié)束后都會主動釋放連接,因此HTTP連接是一種“短連接”,要保持客戶端程序的在線狀態(tài),需要不斷地向服務(wù)器發(fā)起連接請求。通常 的做法是即時不需要獲得任何數(shù)據(jù),客戶端也保持每隔一段固定的時間向服務(wù)器發(fā)送一次“保持連接”的請求,服務(wù)器在收到該請求后對客戶端進行回復(fù),表明知道 客戶端“在線”。若服務(wù)器長時間無法收到客戶端的請求,則認(rèn)為客戶端“下線”,若客戶端長時間無法收到服務(wù)器的回復(fù),則認(rèn)為網(wǎng)絡(luò)已經(jīng)斷開。

下面是一個簡單的HTTP Post application/json數(shù)據(jù)內(nèi)容的請求:

現(xiàn)在我們了解到TCP/IP只是一個協(xié)議棧,就像操作系統(tǒng)的運行機制一樣,必須要具體實現(xiàn),同時還要提供對外的操作接口。就像操作系統(tǒng)會提供標(biāo)準(zhǔn)的編程接口,比如Win32編程接口一樣,TCP/IP也必須對外提供編程接口,這就是Socket?,F(xiàn)在我們知道,Socket跟TCP/IP并沒有必然的聯(lián)系。Socket編程接口在設(shè)計的時候,就希望也能適應(yīng)其他的網(wǎng)絡(luò)協(xié)議。所以,Socket的出現(xiàn)只是可以更方便的使用TCP/IP協(xié)議棧而已,其對TCP/IP進行了抽象,形成了幾個最基本的函數(shù)接口。比如create,listen,accept,connect,read和write等等。

不同語言都有對應(yīng)的建立Socket服務(wù)端和客戶端的庫,下面舉例Nodejs如何創(chuàng)建服務(wù)端和客戶端:

服務(wù)端:

服務(wù)監(jiān)聽9000端口

下面使用命令行發(fā)送http請求和telnet

注意到curl只處理了一次報文。

客戶端

Socket長連接

所謂長連接,指在一個TCP連接上可以連續(xù)發(fā)送多個數(shù)據(jù)包,在TCP連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需要雙方發(fā)檢測包以維持此連接(心跳包),一般需要自己做在線維持。 短連接是指通信雙方有數(shù)據(jù)交互時,就建立一個TCP連接,數(shù)據(jù)發(fā)送完成后,則斷開此TCP連接。比如Http的,只是連接、請求、關(guān)閉,過程時間較短,服務(wù)器若是一段時間內(nèi)沒有收到請求即可關(guān)閉連接。其實長連接是相對于通常的短連接而說的,也就是長時間保持客戶端與服務(wù)端的連接狀態(tài)。

通常的短連接操作步驟是:

連接 數(shù)據(jù)傳輸 關(guān)閉連接;

而長連接通常就是:

連接 數(shù)據(jù)傳輸 保持連接(心跳) 數(shù)據(jù)傳輸 保持連接(心跳) …… 關(guān)閉連接;

什么時候用長連接,短連接?

長連接多用于操作頻繁,點對點的通訊,而且連接數(shù)不能太多情況,。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理 速度會降低很多,所以每個操作完后都不斷開,次處理時直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接。例如:數(shù)據(jù)庫的連接用長連接, 如果用短連接頻繁的通信會造成Socket錯誤,而且頻繁的Socket創(chuàng)建也是對資源的浪費。

什么是心跳包為什么需要:

心跳包就是在客戶端和服務(wù)端間定時通知對方自己狀態(tài)的一個自己定義的命令字,按照一定的時間間隔發(fā)送,類似于心跳,所以叫做心跳包。網(wǎng)絡(luò)中的接收和發(fā)送數(shù)據(jù)都是使用Socket進行實現(xiàn)。但是如果此套接字已經(jīng)斷開(比如一方斷網(wǎng)了),那發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的時候就一定會有問題。可是如何判斷這個套接字是否還可以使用呢?這個就需要在系統(tǒng)中創(chuàng)建心跳機制。其實TCP中已經(jīng)為我們實現(xiàn)了一個叫做心跳的機制。如果你設(shè)置了心跳,那TCP就會在一定的時間(比如你設(shè)置的是3秒鐘)內(nèi)發(fā)送你設(shè)置的次數(shù)的心跳(比如說2次),并且此信息不會影響你自己定義的協(xié)議。也可以自己定義,所謂“心跳”就是定時發(fā)送一個自定義的結(jié)構(gòu)體(心跳包或心跳幀),讓對方知道自己“在線”,以確保鏈接的有效性。

實現(xiàn):

服務(wù)端:

服務(wù)端輸出結(jié)果:

客戶端代碼:

客戶端輸出結(jié)果:

如果想要使傳輸?shù)臄?shù)據(jù)有意義,則必須使用到應(yīng)用層協(xié)議比如Http、Mqtt、Dubbo等?;赥CP協(xié)議上自定義自己的應(yīng)用層的協(xié)議需要解決的幾個問題:

下面我們就一起來定義自己的協(xié)議,并編寫服務(wù)的和客戶端進行調(diào)用:

定義報文頭格式: length:xxxx; xxxx代表數(shù)據(jù)的長度,總長度20,舉例子不嚴(yán)謹(jǐn)。

數(shù)據(jù)表的格式: Json

服務(wù)端:

日志打?。?/p>

客戶端

日志打?。?/p>

客戶端定時發(fā)送自定義協(xié)議數(shù)據(jù)到服務(wù)端,先發(fā)送頭數(shù)據(jù),在發(fā)送內(nèi)容數(shù)據(jù),另外一個定時器發(fā)送心跳數(shù)據(jù),服務(wù)端判斷是心跳數(shù)據(jù),再判斷是不是頭數(shù)據(jù),再是內(nèi)容數(shù)據(jù),然后解析后再發(fā)送數(shù)據(jù)給客戶端。從日志的打印可以看出客戶端先后writeheader和data數(shù)據(jù),服務(wù)端可能在一個data事件里面接收到。

這里可以看到一個客戶端在同一個時間內(nèi)處理一個請求可以很好的工作,但是想象這么一個場景,如果同一時間內(nèi)讓同一個客戶端去多次調(diào)用服務(wù)端請求,發(fā)送多次頭數(shù)據(jù)和內(nèi)容數(shù)據(jù),服務(wù)端的data事件收到的數(shù)據(jù)就很難區(qū)別哪些數(shù)據(jù)是哪次請求的,比如兩次頭數(shù)據(jù)同時到達(dá)服務(wù)端,服務(wù)端就會忽略其中一次,而后面的內(nèi)容數(shù)據(jù)也不一定就對應(yīng)于這個頭的。所以想復(fù)用長連接并能很好的高并發(fā)處理服務(wù)端請求,就需要連接池這種方式了。

什么是Socket連接池,池的概念可以聯(lián)想到是一種資源的,所以Socket連接池,就是維護著一定數(shù)量Socket長連接的。它能自動檢測Socket長連接的有效性,剔除無效的連接,補充連接池的長連接的數(shù)量。從代碼層次上其實是人為實現(xiàn)這種功能的類,一般一個連接池包含下面幾個屬性:

場景: 一個請求過來,首先去資源池要求獲取一個長連接資源,如果空閑隊列里面有長連接,就獲取到這個長連接Socket,并把這個Socket移到正在運行的長連接隊列。如果空閑隊列里面沒有,且正在運行的隊列長度小于配置的連接池資源的數(shù)量,就新建一個長連接到正在運行的隊列去,如果正在運行的不下于配置的資源池長度,則這個請求進入到等待隊列去。當(dāng)一個正在運行的Socket完成了請求,就從正在運行的隊列移到空閑的隊列,并觸發(fā)等待請求隊列去獲取空閑資源,如果有等待的情況。

這里簡單介紹Nodejs的Socket連接池generic-pool模塊的源碼。

主要文件目錄結(jié)構(gòu)

下面介紹庫的使用:

初始化連接池

使用連接池

下面連接池的使用,使用的協(xié)議是我們之前自定義的協(xié)議。

日志打印:

這里看到前面兩個請求都建立了新的Socket連接 socket_pool 127.0.0.connect,定時器結(jié)束后重新發(fā)起兩個請求就沒有建立新的Socket連接了,直接從連接池里面獲取Socket連接資源。

源碼分析

發(fā)現(xiàn)主要的代碼就位于lib文件夾中的Pool.js

構(gòu)造函數(shù):

lib/Pool.js

可以看到包含之前說的空閑的資源隊列,正在請求的資源隊列,正在等待的請求隊列等。

下面查看 Pool.acquire 方法

lib/Pool.js

上面的代碼就按種情況一直走下到最終獲取到長連接的資源,其他更多代碼大家可以自己去深入了解。

關(guān)于linux心跳包c的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價格厚道的香港/美國云服務(wù)器和獨立服務(wù)器。創(chuàng)新互聯(lián)成都老牌IDC服務(wù)商,專注四川成都IDC機房服務(wù)器托管/機柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機房租用、服務(wù)器托管、機柜租賃、大帶寬租用,可選線路電信、移動、聯(lián)通等。


本文名稱:Linux心跳包C編程指南(linux心跳包c)
文章地址:http://m.5511xx.com/article/cojjhoe.html