導航:首頁 > 操作系統 > linux建立tcp連接

linux建立tcp連接

發布時間:2023-06-07 05:53:38

1. linux tcp/ip 網路通信編程

/*************************************
文件名:server.c
linux下socket網路編程簡例-服務端程序
伺服器埠設為0x8888(埠和地址可根據實際情況更改,或者使用參數傳入)
伺服器地址設為192.168.1.104
作者:kikilizhm#163.com(將#換為@)
*/
#include<stdlib.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/socket.h>
#include<linux/in.h>
#include<string.h>
intmain()
{
intsfp,nfp;/*定義兩個描述符*/
structsockaddr_ins_add,c_add;
intsin_size;
unsignedshortportnum=0x8888;/*服務端使用埠*/
printf("Hello,welcometomyserver! ");
sfp=socket(AF_INET,SOCK_STREAM,0);
if(-1==sfp)
{
printf("socketfail! ");
return-1;
}
printf("socketok! ");
/*填充伺服器埠地址信息,以便下面使用此地址和埠監聽*/
bzero(&s_add,sizeof(structsockaddr_in));
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=htonl(INADDR_ANY);/*這里地址使用全0,即所有*/
s_add.sin_port=htons(portnum);
/*使用bind進行綁定埠*/
if(-1==bind(sfp,(structsockaddr*)(&s_add),sizeof(structsockaddr)))
{
printf("bindfail! ");
return-1;
}
printf("bindok! ");
/*開始監聽相應的埠*/
if(-1==listen(sfp,5))
{
printf("listenfail! ");
return-1;
}
printf("listenok ");
while(1)
{
sin_size=sizeof(structsockaddr_in);
/*accept服務端使用函數,調用時即進入阻塞狀態,等待用戶進行連接,在沒有客戶端進行連接時,程序停止在此處,
不會看到後面的列印,當有客戶端進行連接時,程序馬上執行一次,然後再次循環到此處繼續等待。
此處accept的第二個參數用於獲取客戶端的埠和地址信息。
*/
nfp=accept(sfp,(structsockaddr*)(&c_add),&sin_size);
if(-1==nfp)
{
printf("acceptfail! ");
return-1;
}
printf("acceptok! Serverstartgetconnectfrom%#x:%#x ",ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port));
/*這里使用write向客戶端發送信息,也可以嘗試使用其他函數實現*/
if(-1==write(nfp,"hello,welcometomyserver ",32))
{
printf("writefail! ");
return-1;
}
printf("writeok! ");
close(nfp);
}
close(sfp);
return0;
}
/*************************************
文件名:client.c
linux下socket網路編程簡例-客戶端程序
伺服器埠設為0x8888(埠和地址可根據實際情況更改,或者使用參數傳入)
伺服器地址設為192.168.1.104
作者:kikilizhm#163.com(將#換為@)
*/
#include<stdlib.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/socket.h>
#include<linux/in.h>
#include<string.h>
intmain()
{
intcfd;/*文件描述符*/
intrecbytes;
intsin_size;
charbuffer[1024]={0};/*接受緩沖區*/
structsockaddr_ins_add,c_add;/*存儲服務端和本端的ip、埠等信息結構體*/
unsignedshortportnum=0x8888;/*服務端使用的通信埠,可以更改,需和服務端相同*/
printf("Hello,welcometoclient! ");
/*建立socket使用網際網路,TCP流傳輸*/
cfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==cfd)
{
printf("socketfail! ");
return-1;
}
printf("socketok! ");
/*構造伺服器端的ip和埠信息,具體結構體可以查資料*/
bzero(&s_add,sizeof(structsockaddr_in));
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=inet_addr("192.168.1.104");/*ip轉換為4位元組整形,使用時需要根據服務端ip進行更改*/
s_add.sin_port=htons(portnum);/*這里htons是將short型數據位元組序由主機型轉換為網路型,其實就是
將2位元組數據的前後兩個位元組倒換,和對應的ntohs效果、實質相同,只不過名字不同。htonl和ntohl是
操作的4位元組整形。將0x12345678變為0x78563412,名字不同,內容兩兩相同,一般情況下網路為大端,
PPC的cpu為大端,x86的cpu為小端,arm的可以配置大小端,需要保證接收時位元組序正確。
*/
printf("s_addr=%#x,port:%#x ",s_add.sin_addr.s_addr,s_add.sin_port);/*這里列印出的是小端
和我們平時看到的是相反的。*/
/*客戶端連接伺服器,參數依次為socket文件描述符,地址信息,地址結構大小*/
if(-1==connect(cfd,(structsockaddr*)(&s_add),sizeof(structsockaddr)))
{
printf("connectfail! ");
return-1;
}
printf("connectok! ");
/*連接成功,從服務端接收字元*/
if(-1==(recbytes=read(cfd,buffer,1024)))
{
printf("readdatafail! ");
return-1;
}
printf("readok REC: ");
buffer[recbytes]='';
printf("%s ",buffer);
getchar();/*此句為使程序暫停在此處,可以使用netstat查看當前的連接*/
close(cfd);/*關閉連接,本次通信完成*/
return0;
}

2. Linux系統支持的最大TCP連接是多少

1.首先,客戶端和伺服器建立的每個TCP連接都會佔用伺服器內存,所以最大TCP連接數和內存成正比。簡單估算為最大內存除以單TCP連接佔用的最小內存
2.Linux操作系統中,一切都是文件。所以每個TCP連接,都會打開一個文件。為此Linux操作系統限制了每個用戶能打開的文件數量,通過ulimit -n 查看。修改方式:
vi /etc/security/limits.conf文件,在文件中添加如下行(限制修改為10240):
speng soft nofile 10240
speng hard nofile 10240
3.Linux操作系統中,TCP連接數量還受到埠數量限制,由於埠號只有1-65535,所以最大TCP連接數也只有65535個(包括系統埠1-1024)
4.Linux操作系統對所有用戶最大能打開文件的限制:cat /proc/sys/fs/file-max。
5.網路核心模塊對tcp連接的限制(最大不能超過65535):
vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65000
6.防火牆對tcp連接的限制
綜上,在Linux操作系統中,首先對TCP連接數量的限制依次有:埠數量限制,網路核心限制,最大文件數量限制(因為每建立一個連接就要打開一個文件),防火牆限制,用戶打開文件限制
都是傳智播客出版的書上的知識,他們官網也都有。可以去官網多看看視頻學學。

3. Linux下TCP客戶端重連還需要重新建立套接字嗎

從函數調用上來分析(msdn):一旦完成了套接字的連接,應當將套接字關閉,並且釋放其套接字句柄所佔用的所有資源。真正釋放一個已經打開的套接字句柄的資源直接調用closesocket即可,但要明白closesocket的調用可能會帶來負面影響,具體的影響和...

4. linux建立TCP伺服器後,TCP客戶端與伺服器連接成功後,怎樣獲取客戶端的MAC地址

我認為你是從 socket中取不到這部分的信息的.

你得再操作 arp的緩存部分才行. ARP那部分如果在特殊情況,很亂套.比如有攻擊或是IP地址設置有沖突啥地.

---
詳細的C語言怎麼操作ARP緩存我不太清楚. 但你如果想知道.就得查一下這部分怎麼做了.
高層的socket操作是得不到的.

只有直連網段的計算機有MAC地址信息.經過路由來的數據包.取不到.

5. 暢談linux下TCP(上)

tcp 協議 是互聯網中最常用的協議 , 開發人員基本上天天和它打交道,對它進行深入了解。 可以幫助我們排查定位bug和進行程序優化。下面我將就TCP幾個點做深入的探討

客戶端:收到 ack 後 分配連接資源。 發送數據
伺服器 : 收到 syn 後立即 分配連接資源

客戶端:收到ACK, 立即分配資源
伺服器:收到ACK, 立即分配資源

既然三次握手也不是100%可靠, 那四次,五次,六次。。。呢? 其實都一樣,不管多少次都有丟包問題。

client 只發送一個 SYN, server 分配一個tcb, 放入syn隊列中。 這時候連接叫 半連接 狀態;如果server 收不到 client 的ACK, 會不停重試 發送 ACK-SYN 給client 。重試間隔 為 2 的 N 次方 疊加(2^0 , 2^1, 2^2 ....);直至超時才釋放syn隊列中的這個 TCB;
在半連接狀態下, 一方面會佔用隊列配額資源,另一方面佔用內存資源。我們應該讓半連接狀態存在時間盡可能的小

當client 向一個未打開的埠發起連接請求時,會收到一個RST回復包

當listen 的 backlog 和 somaxconn 都設置了得時候, 取兩者min值

Recv-Q 是accept 隊列當前個數, Send-Q 設置最大值

這種SYN洪水攻擊是一種常見攻擊方式,就是利用半連接隊列特性,占滿syn 隊列的 資源,導致 client無法連接上。
解決方案:

為什麼不像握手那樣合並成三次揮手? 因為和剛開始連接情況,連接是大家都從0開始, 關閉時有歷史包袱的。server(被動關閉方) 收到 client(主動關閉方) 的關閉請求FIN包。 這時候可能還有未發送完的數據,不能丟棄。 所以需要分開。事實可能是這樣

當然,在沒有待發數據,並且允許 Delay ACK 情況下, FIN-ACK合並還是非常常見的事情,這是三次揮手是可以的。

同上

CLOSE_WAIT 是被動關閉方才有的狀態

被動關閉方 [收到 FIN 包 發送 ACK 應答] 到 [發送FIN, 收到ACK ] 期間的狀態為 CLOSE_WAIT, 這個狀態仍然能發送數據。 我們叫做 半關閉 , 下面用個例子來分析:

這個是我實際生產環境碰到的一個問題,長連接會話場景,server端收到client的rpc call 請求1,處理發現請求包有問題,就強制關閉結束這次會話, 但是 因為client 發送 第二次請求之前,並沒有去調用recv,所以並不知道 這個連接被server關閉, 繼續發送 請求2 , 此時是半連接,能夠成功發送到對端機器,但是recv結果後,遇到連接已經關閉錯誤。

如果 client 和 server 恰好同時發起關閉連接。這種情況下,兩邊都是主動連接,都會進入 TIME_WAIT狀態

1、 被動關閉方在LAST_ACK狀態(已經發送FIN),等待主動關閉方的ACK應答,但是 ACK丟掉, 主動方並不知道,以為成功關閉。因為沒有TIME_WAIT等待時間,可以立即創建新的連接, 新的連接發送SYN到前面那個未關閉的被動方,被動方認為是收到錯誤指令,會發送RST。導致創建連接失敗。

2、 主動關閉方斷開連接,如果沒有TIME_WAIT等待時間,可以馬上建立一個新的連接,但是前一個已經斷開連接的,延遲到達的數據包。 被新建的連接接收,如果剛好seq 和 ack欄位 都正確, seq在滑動窗口范圍內(只能說機率非常小,但是還是有可能會發生),會被當成正確數據包接收,導致數據串包。 如果不在window范圍內,則沒有影響( 發送一個確認報文(ack 欄位為期望ack的序列號,seq為當前發送序列號),狀態變保持原樣)

TIME_WAIT 問題比較比較常見,特別是CGI機器,並發量高,大量連接後段服務的tcp短連接。因此也衍生出了多種手段解決。雖然每種方法解決不是那麼完美,但是帶來的好處一般多於壞處。還是在日常工作中會使用。
1、改短TIME_WAIT 等待時間

這個是第一個想到的解決辦法,既然等待時間太長,就改成時間短,快速回收埠。但是實際情況往往不樂觀,對於並發的機器,你改多短才能保證回收速度呢,有時候幾秒鍾就幾萬個連接。太短的話,就會有前面兩種問題小概率發生。

2、禁止Socket lingering

這種情況下關閉連接,會直接拋棄緩沖區中待發送的數據,會發送一個RST給對端,相當於直接拋棄TIME_WAIT, 進入CLOSE狀態。同樣因為取消了 TIME_WAIT 狀態,會有前面兩種問題小概率發生。

3、tcp_tw_reuse
net.ipv4.tcp_tw_reuse選項是 從 TIME_WAIT 狀態的隊列中,選取條件:1、remote 的 ip 和埠相同, 2、選取一個時間戳小於當前時間戳; 用來解決埠不足的尷尬。

現在埠可以復用了,看看如何面對前面TIME_WAIT 那兩種問題。 我們仔細回顧用一下前面兩種問題。 都是在新建連接中收到老連接的包導致的問題 , 那麼如果我能在新連接中識別出此包為非法包,是不是就可以丟掉這些無用包,解決問題呢。

需要實現這些功能,需要擴展一下tcp 包頭。 增加 時間戳欄位。 發送者 在每次發送的時候。 在tcp包頭裡面帶上發送時候的時間戳。 當接收者接收的時候,在ACK應答中除了TCP包頭中帶自己此時發送的時間戳,並且把收到的時間戳附加在後面。也就是說ACK包中有兩個時間戳欄位。結構如下:

那我們接下來一個個分析tcp_tw_reuse是如何解決TIME_WAIT的兩個問題的

4、tcp_tw_recycle

tcp_tw_recycle 也是藉助 timestamp機制。顧名思義, tcp_tw_reuse 是復用 埠,並不會減少 TIME-WAIT 數量。你去查詢機器上TIME-WAIT 數量,還是 幾千幾萬個,這點對有強迫症的同學感覺很不舒服。tcp_tw_recycle 是 提前 回收 TIME-WAIT資源。會減少 機器上 TIME-WAIT 數量。

tcp_tw_recycle 工作原理是。

閱讀全文

與linux建立tcp連接相關的資料

熱點內容
交警app怎麼綁定本人幾輛車 瀏覽:985
彩虹六號如何人工伺服器 瀏覽:632
mc伺服器地址怎麼登入 瀏覽:556
蘋果app怎麼掃描二維碼下載 瀏覽:959
css文件在線解壓 瀏覽:154
36歲程序員近況 瀏覽:283
哪裡可以下載不加密的歌 瀏覽:934
隱藏文件夾是什麼梗 瀏覽:918
插件注冊命令 瀏覽:497
梁一端加密一端不加密規范 瀏覽:82
代碼行數統計命令 瀏覽:104
單片機中2K表示什麼 瀏覽:482
紫禁城為什麼會斷開伺服器 瀏覽:580
華為手機的方舟編譯器在哪呢 瀏覽:125
下載壓縮虐殺原形2 瀏覽:907
linux腳本cd 瀏覽:168
間架結構pdf 瀏覽:845
重慶農村商業銀行app怎麼老出問題 瀏覽:473
慧編程配置要求 瀏覽:675
數控機床編程與操作視頻 瀏覽:462