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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
深入了解LinuxTCP的例子(linuxtcp例子)

TCP(Tranission Control Protocol)是一種網(wǎng)絡(luò)傳輸層協(xié)議,主要用于保證數(shù)據(jù)在網(wǎng)絡(luò)中可靠傳輸。在 Linux 操作系統(tǒng)中,TCP 協(xié)議是非常重要且廣泛使用的協(xié)議,因此深入了解 Linux TCP 將有助于我們更好地理解 Linux 網(wǎng)絡(luò)編程和網(wǎng)絡(luò)優(yōu)化。

我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、漢陽(yáng)ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的漢陽(yáng)網(wǎng)站制作公司

本文將介紹一些常用的 Linux TCP 相關(guān)命令和工具,并通過(guò)一個(gè) TCP 客戶端和服務(wù)器的例子,深入了解 TCP 的基本流程和一些常見(jiàn)的 TCP 問(wèn)題。

1. 常用 Linux TCP 命令和工具

1.1 netstat

netstat 命令是一個(gè)非常常用的網(wǎng)絡(luò)命令,可以用于顯示各種網(wǎng)絡(luò)信息。在查看 TCP 相關(guān)信息時(shí),我們可以使用以下命令來(lái)查看當(dāng)前連接的狀態(tài)信息:

“`bash

netstat -ant | grep ESTABLISHED

“`

該命令將顯示當(dāng)前所有已建立的連接信息,包括本地 IP 和端口號(hào)、遠(yuǎn)程 IP 和端口號(hào)、TCP 的狀態(tài)等信息。

1.2 tcpdump

tcpdump 是一個(gè)用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的命令行工具。通過(guò) tcpdump,我們可以詳細(xì)查看網(wǎng)絡(luò)通信中的各種細(xì)節(jié)信息,包括TCP包的頭部信息、數(shù)據(jù)長(zhǎng)度、序列號(hào)、確認(rèn)號(hào)等等。例如,我們可以使用以下命令來(lái)捕獲指定端口的數(shù)據(jù)包:

“`bash

sudo tcpdump -n -i eth0 port 8080

“`

該命令將捕獲所有進(jìn)入或離開 eth0 接口上的 8080 端口的 TCP 數(shù)據(jù)包,并輸出詳細(xì)信息。

1.3 tcptrace

tcptrace 是一個(gè)用于分析和生成 TCP 連接數(shù)據(jù)包的工具。通過(guò) tcptrace,我們可以詳細(xì)了解 TCP 連接的生命周期,了解各個(gè)階段的數(shù)據(jù)傳輸情況、時(shí)延、丟包等信息。例如,我們可以使用以下命令來(lái)生成 TCP 連接的日志文件:

“`bash

sudo tcpdump -n -s0 -w tcpdump.log port 8080

sudo tcptrace -xS tcpdump.log

“`

該命令將捕獲本地 8080 端口的所有 TCP 數(shù)據(jù)包,并將其轉(zhuǎn)儲(chǔ)到 tcpdump.log 文件中。然后我們可以使用 tcptrace 命令來(lái)分析生成數(shù)據(jù)文件。

2. TCP 客戶端和服務(wù)器的例子

在 Linux 中,我們可以使用各種編程語(yǔ)言來(lái)編寫 TCP 客戶端和服務(wù)器程序。下面,我們將使用 C 語(yǔ)言來(lái)編寫一個(gè)簡(jiǎn)單的 TCP 客戶端和服務(wù)器程序,并通過(guò)這個(gè)例子來(lái)深入了解 TCP 的基本流程和一些常見(jiàn)的 TCP 問(wèn)題。

2.1 TCP 服務(wù)器

下面是一個(gè)簡(jiǎn)單的 TCP 服務(wù)器程序的示例代碼:

“`c

#include

#include

#include

#include

#include

#include

#include

#define PORT 8080

#define BACKLOG 10

int mn()

{

int sockfd, new_fd;

struct sockaddr_in my_addr;

struct sockaddr_in their_addr;

size_t sin_size;

char buf[1024];

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror(“socket”);

exit(1);

}

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(PORT);

my_addr.sin_addr.s_addr = INADDR_ANY;

bzero(&(my_addr.sin_zero), 8);

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)

{

perror(“bind”);

exit(1);

}

if (listen(sockfd, BACKLOG) == -1)

{

perror(“l(fā)isten”);

exit(1);

}

printf(“server started listening on %d…\n”, PORT);

while (1)

{

if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1)

{

perror(“accept”);

continue;

}

printf(“server got connection from %s\n”, inet_ntoa(their_addr.sin_addr));

send(new_fd, “Hello, world!”, 13, 0);

close(new_fd);

}

close(sockfd);

return 0;

}

“`

上述代碼中,我們首先通過(guò) socket 函數(shù)創(chuàng)建了一個(gè)套接字,然后通過(guò) bind 函數(shù)將該套接字與本地的 IP 地址和端口號(hào)綁定。接著,我們調(diào)用 listen 函數(shù)開啟服務(wù),準(zhǔn)備接受來(lái)自 TCP 客戶端的連接請(qǐng)求。在主循環(huán)中,我們通過(guò) accept 函數(shù)等待客戶端的連接請(qǐng)求,一旦接收到連接請(qǐng)求,就使用 send 函數(shù)向客戶端發(fā)送歡迎信息,并使用 close 函數(shù)關(guān)閉連接。

2.2 TCP 客戶端

下面是一個(gè)簡(jiǎn)單的 TCP 客戶端程序的示例代碼:

“`c

#include

#include

#include

#include

#include

#include

#include

#define PORT 8080

#define SERVER_ADDR “127.0.0.1”

int mn()

{

int sockfd;

struct sockaddr_in server_addr;

char buf[1024];

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror(“socket”);

exit(1);

}

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(PORT);

server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);

bzero(&(server_addr.sin_zero), 8);

if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)

{

perror(“connect”);

exit(1);

}

recv(sockfd, buf, 1024, 0);

printf(“client received: %s\n”, buf);

close(sockfd);

return 0;

}

“`

上述代碼中,我們同樣首先通過(guò) socket 函數(shù)創(chuàng)建了一個(gè)套接字,然后通過(guò) connect 函數(shù)連接到遠(yuǎn)程服務(wù)器的 IP 地址和端口號(hào)。在連接成功后,我們通過(guò) recv 函數(shù)等待服務(wù)器的響應(yīng),并將其輸出到控制臺(tái)。我們通過(guò) close 函數(shù)關(guān)閉連接。

3.

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

  • TCP那些事兒
  • Linux TCP/IP協(xié)議棧數(shù)據(jù)包處理流程及代碼實(shí)現(xiàn)分析

TCP那些事兒

目錄:

以前畢盯洞我也認(rèn)為TCP是相當(dāng)?shù)讓拥臇|西,我永遠(yuǎn)不需要去了解它。雖然差不多是這樣,但是實(shí)際生活中,你依然可能遇見(jiàn)和TCP算法相關(guān)的bug,這時(shí)候懂一些TCP的知識(shí)就至關(guān)重要了。(

本文也可以引申為,系統(tǒng)調(diào)用,操作系統(tǒng)這些都很重要,這個(gè)道理適用于很多東西

這里推薦一篇小短文, 人人都應(yīng)該懂點(diǎn)TCP

使用TCP協(xié)議通信的雙方必須先建立TCP連接,并在內(nèi)核中為該連接維持一些必要的數(shù)據(jù)結(jié)構(gòu),比如連接的狀態(tài)、讀寫緩沖區(qū)、定時(shí)器等。當(dāng)通信結(jié)束時(shí),雙方必須關(guān)閉連接以釋放這些內(nèi)核數(shù)據(jù)。TCP服務(wù)基于流,源源不斷從一端流向另一端,發(fā)送端可以逐字節(jié)寫入,接收端可以逐字節(jié)讀出,無(wú)需分段。

需要注意的幾點(diǎn):

TCP狀態(tài)(11種):

eg.

以上為TCP三次握手的狀態(tài)變遷

以下為TCP四次揮手的狀態(tài)變遷

服務(wù)器通過(guò) listen 系統(tǒng)調(diào)用進(jìn)入

LISTEN

狀態(tài),被動(dòng)等待客戶端連接,也就是所謂的被動(dòng)打開。一旦監(jiān)聽到SYN(同步報(bào)文段)請(qǐng)求,就將該連接放入內(nèi)核的等待隊(duì)列,并向客戶端發(fā)送帶SYN的ACK(確認(rèn)報(bào)文段),此時(shí)該連接處于

SYN_RECVD

狀態(tài)。如果服務(wù)器收到客戶端返回的ACK,則轉(zhuǎn)到

ESTABLISHED

狀態(tài)。這個(gè)狀態(tài)就是連接雙方能進(jìn)行全雙工數(shù)據(jù)傳輸?shù)臓顟B(tài)。

而當(dāng)客戶端主動(dòng)關(guān)閉連接時(shí),服務(wù)器收到FIN報(bào)文,通過(guò)返回ACK使連接進(jìn)入

CLOSE_WAIT

狀態(tài)。此狀態(tài)表示——等待服務(wù)器應(yīng)用程序關(guān)閉連接。通常,服務(wù)器檢測(cè)到客戶端關(guān)閉連接之后,也會(huì)立即給客戶端發(fā)送一個(gè)FIN來(lái)關(guān)閉連接,使連接轉(zhuǎn)移到

LAST_ACK

狀態(tài),等待客戶端對(duì)最后一個(gè)FIN結(jié)束報(bào)文段的最后一次確認(rèn),一旦確認(rèn)完成,連接就徹底關(guān)閉了。

客戶端通過(guò) connect 系統(tǒng)調(diào)用主動(dòng)與服務(wù)器建立連接。此系統(tǒng)調(diào)用會(huì)首先給服務(wù)器發(fā)一個(gè)SYN,使連接進(jìn)入

SYN_SENT

狀態(tài)。

connect 調(diào)用可能因?yàn)閮煞N原因失敗:1. 目標(biāo)端口不存在(未被任何進(jìn)程監(jiān)聽)護(hù)著該端口被

TIME_WAIT

狀態(tài)的連接占用( 詳見(jiàn)后文 )。2. 連接超時(shí),在超時(shí)時(shí)間內(nèi)未收到服務(wù)器的ACK。

如果 connect 調(diào)用失敗,則連接返回初始的

CLOSED

狀態(tài),如果調(diào)用成功,則轉(zhuǎn)到

ESTABLISHED

狀態(tài)。

客戶端執(zhí)行主動(dòng)關(guān)閉時(shí),它會(huì)向服務(wù)器發(fā)送一個(gè)FIN,連接進(jìn)入

TIME_WAIT_1

狀態(tài),如果收到服務(wù)器的ACK,進(jìn)入

TIME_WAIT_2

狀態(tài)。此時(shí)服務(wù)器處于

CLOSE_WAIT

狀態(tài),這一對(duì)狀態(tài)是可能發(fā)生辦關(guān)閉的狀態(tài)(詳見(jiàn)后文)。此時(shí)如果服務(wù)器發(fā)送FIN關(guān)閉連接,則客戶端會(huì)發(fā)送ACK進(jìn)行確認(rèn)并進(jìn)入

TIME_WAIT

狀態(tài)。

流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來(lái)得及接收。

接收方發(fā)送的確認(rèn)報(bào)文中的窗口字段可以用來(lái)控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將窗口字段設(shè)置為 0,則發(fā)送方不能發(fā)送數(shù)據(jù)。

如果網(wǎng)絡(luò)出現(xiàn)擁塞,分組將會(huì)丟失,此時(shí)發(fā)送方會(huì)繼續(xù)重傳手枯,從而導(dǎo)致網(wǎng)絡(luò)擁塞程度更高。因此當(dāng)出現(xiàn)擁塞時(shí),應(yīng)當(dāng)控制發(fā)送方的速率。這一點(diǎn)和流量控制很像,但是出發(fā)點(diǎn)不同。

流量控制是為了讓接收方能來(lái)得及接收,而擁塞控制是為了降低整個(gè)網(wǎng)絡(luò)的擁塞程度。

TCP 主要通過(guò)四種算法來(lái)進(jìn)行擁塞控制:

慢開始、擁塞避免、快重傳、快恢復(fù)。

在Linux下有多種則埋實(shí)現(xiàn),比如reno算法,vegas算法和cubic算法等。

發(fā)送方需要維護(hù)一個(gè)叫做擁塞窗口(cwnd)的狀態(tài)變量,注意擁塞窗口與發(fā)送方窗口的區(qū)別:擁塞窗口只是一個(gè)狀態(tài)變量,實(shí)際決定發(fā)送方能發(fā)送多少數(shù)據(jù)的是發(fā)送方窗口。

為了便于討論,做如下假設(shè):

發(fā)送的最初執(zhí)行慢開始,令 cwnd=1,發(fā)送方只能發(fā)送 1 個(gè)報(bào)文段;當(dāng)收到確認(rèn)后,將 cwnd 加倍,因此之后發(fā)送方能夠發(fā)送的報(bào)文段數(shù)量為:2、4、8 …

注意到慢開始每個(gè)輪次都將 cwnd 加倍,這樣會(huì)讓 cwnd 增長(zhǎng)速度非???,從而使得發(fā)送方發(fā)送的速度增長(zhǎng)速度過(guò)快,網(wǎng)絡(luò)擁塞的可能也就更高。設(shè)置一個(gè)慢開始門限 ssthresh,當(dāng) cwnd >= ssthresh 時(shí),進(jìn)入擁塞避免,每個(gè)輪次只將 cwnd 加 1。

如果出現(xiàn)了超時(shí),則令 ssthresh = cwnd/2,然后重新執(zhí)行慢開始。

在接收方,要求每次接收到報(bào)文段都應(yīng)該對(duì)最后一個(gè)已收到的有序報(bào)文段進(jìn)行確認(rèn)。例如已經(jīng)接收到 M1 和 M2,此時(shí)收到 M4,應(yīng)當(dāng)發(fā)送對(duì) M2 的確認(rèn)。

在發(fā)送方,如果收到三個(gè)重復(fù)確認(rèn),那么可以知道下一個(gè)報(bào)文段丟失,此時(shí)執(zhí)行快重傳,立即重傳下一個(gè)報(bào)文段。例如收到三個(gè) M2,則 M3 丟失,立即重傳 M3。

在這種情況下,只是丟失個(gè)別報(bào)文段,而不是網(wǎng)絡(luò)擁塞。因此執(zhí)行快恢復(fù),令 ssthresh = cwnd/2 ,cwnd = ssthresh,注意到此時(shí)直接進(jìn)入擁塞避免。

慢開始和快恢復(fù)的快慢指的是 cwnd 的設(shè)定值,而不是 cwnd 的增長(zhǎng)速率。慢開始 cwnd 設(shè)定為 1,而快恢復(fù) cwnd 設(shè)定為 ssthresh。

??發(fā)送端的每個(gè)TCP報(bào)文都必須得到接收方的應(yīng)答,才算傳輸成功。

??TCP為每個(gè)TCP報(bào)文段都維護(hù)一個(gè)重傳定時(shí)器。

??發(fā)送端在發(fā)出一個(gè)TCP報(bào)文段之后就啟動(dòng)定時(shí)器,如果在定時(shí)時(shí)間類未收到應(yīng)答,它就將重發(fā)該報(bào)文段并重置定時(shí)器。

??因?yàn)門CP報(bào)文段最終在網(wǎng)絡(luò)層是以IP數(shù)據(jù)報(bào)的形式發(fā)送,而IP數(shù)據(jù)報(bào)到達(dá)接收端可能是亂序或者重復(fù)的。TCP協(xié)議會(huì)對(duì)收到的TCP報(bào)文進(jìn)行重排、整理,確保順序正確。

TCP報(bào)文段所攜帶的應(yīng)用程序數(shù)據(jù)按照長(zhǎng)度分為兩種:

交互數(shù)據(jù)

成塊數(shù)據(jù)

對(duì)于什么是粘包、拆包問(wèn)題,我想先舉兩個(gè)簡(jiǎn)單的應(yīng)用場(chǎng)景:

對(duì)于之一種情況,服務(wù)端的處理流程可以是這樣的:當(dāng)客戶端與服務(wù)端的連接建立成功之后,服務(wù)端不斷讀取客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),當(dāng)客戶端與服務(wù)端連接斷開之后,服務(wù)端知道已經(jīng)讀完了一條消息,然后進(jìn)行解碼和后續(xù)處理…。對(duì)于第二種情況,如果按照上面相同的處理邏輯來(lái)處理,那就有問(wèn)題了,我們來(lái)看看

第二種情況

下客戶端發(fā)送的兩條消息遞交到服務(wù)端有可能出現(xiàn)的情況:

之一種情況:

服務(wù)端一共讀到兩個(gè)數(shù)據(jù)包,之一個(gè)包包含客戶端發(fā)出的之一條消息的完整信息,第二個(gè)包包含客戶端發(fā)出的第二條消息,那這種情況比較好處理,服務(wù)器只需要簡(jiǎn)單的從網(wǎng)絡(luò)緩沖區(qū)去讀就好了,之一次讀到之一條消息的完整信息,消費(fèi)完再?gòu)木W(wǎng)絡(luò)緩沖區(qū)將第二條完整消息讀出來(lái)消費(fèi)。

第二種情況:

服務(wù)端一共就讀到一個(gè)數(shù)據(jù)包,這個(gè)數(shù)據(jù)包包含客戶端發(fā)出的兩條消息的完整信息,這個(gè)時(shí)候基于之前邏輯實(shí)現(xiàn)的服務(wù)端就蒙了,因?yàn)榉?wù)端不知道之一條消息從哪兒結(jié)束和第二條消息從哪兒開始,這種情況其實(shí)是發(fā)生了TCP粘包。

第三種情況:

服務(wù)端一共收到了兩個(gè)數(shù)據(jù)包,之一個(gè)數(shù)據(jù)包只包含了之一條消息的一部分,之一條消息的后半部分和第二條消息都在第二個(gè)數(shù)據(jù)包中,或者是之一個(gè)數(shù)據(jù)包包含了之一條消息的完整信息和第二條消息的一部分信息,第二個(gè)數(shù)據(jù)包包含了第二條消息的剩下部分,這種情況其實(shí)是發(fā)送了TCP拆,因?yàn)榘l(fā)生了一條消息被拆分在兩個(gè)包里面發(fā)送了,同樣上面的服務(wù)器邏輯對(duì)于這種情況是不好處理的。

我們知道tcp是以流動(dòng)的方式傳輸數(shù)據(jù),傳輸?shù)淖钚挝粸橐粋€(gè)報(bào)文段(segment)。tcp Header中有個(gè)Options標(biāo)識(shí)位,常見(jiàn)的標(biāo)識(shí)為mss(Maximum Segment Size)指的是,連接層每次傳輸?shù)臄?shù)據(jù)有個(gè)更大限制MTU(Maximum Tranission Unit),一般是1500比特,超過(guò)這個(gè)量要分成多個(gè)報(bào)文段,mss則是這個(gè)更大限制減去TCP的header,光是要傳輸?shù)臄?shù)據(jù)的大小,一般為1460比特。換算成字節(jié),也就是180多字節(jié)。

tcp為提高性能,發(fā)送端會(huì)將需要發(fā)送的數(shù)據(jù)發(fā)送到緩沖區(qū),等待緩沖區(qū)滿了之后,再將緩沖中的數(shù)據(jù)發(fā)送到接收方。同理,接收方也有緩沖區(qū)這樣的機(jī)制,來(lái)接收數(shù)據(jù)。

發(fā)生TCP粘包、拆包主要是由于下面一些原因:

既然知道了tcp是無(wú)界的數(shù)據(jù)流,且協(xié)議本身無(wú)法避免粘包,拆包的發(fā)生,那我們只能在應(yīng)用層數(shù)據(jù)協(xié)議上,加以控制。通常在制定傳輸數(shù)據(jù)時(shí),可以使用如下方法:

寫了一個(gè)簡(jiǎn)單的 golang 版的tcp服務(wù)器實(shí)例,僅供參考:

例子

參考和推薦閱讀書目:

注釋:

eg.

Linux TCP/IP協(xié)議棧數(shù)據(jù)包處理流程及代碼實(shí)現(xiàn)分析

好吧,我來(lái)回答吧,首先是網(wǎng)卡驅(qū)動(dòng)程序捕銀衡獲到數(shù)據(jù)包,做檢驗(yàn)無(wú)誤后,和DMA以及CPU交互,然后由DMA和驅(qū)動(dòng)程序創(chuàng)建BD表,然后分配skbuf(LINUX下)數(shù)據(jù)結(jié)構(gòu)保存獲得的數(shù)據(jù)幀,內(nèi)核通過(guò)協(xié)議棧處理這個(gè)skbuf,通常是層層剝離每個(gè)層的首部,然后傳到上一層,細(xì)節(jié)就是一個(gè)變量做偏移量,每次做一個(gè)首部偏移讀取租搏鍵首部數(shù)據(jù),識(shí)別本層協(xié)議類型以及下一層協(xié)議類型,具體過(guò)程就是這個(gè)網(wǎng)絡(luò)原理的過(guò)程,請(qǐng)參考《TCP/IP詳解卷一》《linux設(shè)備驅(qū)動(dòng)程序》《understanding linux network internals》弊巧《Unix網(wǎng)絡(luò)編程卷一》等。

太高聲了

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

創(chuàng)新互聯(lián)服務(wù)器托管擁有成都T3+級(jí)標(biāo)準(zhǔn)機(jī)房資源,具備完善的安防設(shè)施、三線及BGP網(wǎng)絡(luò)接入帶寬達(dá)10T,機(jī)柜接入千兆交換機(jī),能夠有效保證服務(wù)器托管業(yè)務(wù)安全、可靠、穩(wěn)定、高效運(yùn)行;創(chuàng)新互聯(lián)專注于成都服務(wù)器托管租用十余年,得到成都等地區(qū)行業(yè)客戶的一致認(rèn)可。


分享標(biāo)題:深入了解LinuxTCP的例子(linuxtcp例子)
瀏覽地址:http://www.5511xx.com/article/djioojh.html