Linux網路程式設計connect 函式的使用

2021-06-22 18:29:36 字數 3204 閱讀 2474

在乙個 client/server模型的網路應用中,客戶端的呼叫序列大致如下:

socket -> connect -> recv/send -> close

其中socket沒有什麼可疑問的,主要是建立乙個套接字用於與服務端交換資料,並且通常它會迅速返回,此時並沒有資料通過網絡卡傳送出去,而緊隨其後的connect函式則會產生網路資料的傳送,tcp的三次握手也正是在此時開始,connect會先傳送乙個syn包給服務端,並從最初始的closed狀態進入到syn_sent狀態,在此狀態等待服務端的確認包,通常情況下這個確認包會很快到達,以致於我們根本無法使用netstat命令看到syn_sent狀態的存在,不過我們可以做乙個極端情況的模擬,讓客戶端去連線乙個隨意指定伺服器(如ip位址為88.88.88.88),因為該伺服器很明顯不會反饋給我們syn包的確認包(syn ack),客戶端就會在一定時間內處於syn_sent狀態,並在預定的超時時間(比如3分鐘)之後從connect函式返回,connect呼叫一旦失敗(沒能到達established狀態)這個套接字便不可用,若要再次呼叫connect函式則必須要重新使用socket函式建立新的套接字。

下面結合例項分析,客戶端**如下:

[cpp]view plain

copy

/*** client.c

** tcp client program, it is a ****** example only.

* writen by: zhou jianchun

* date: 2011.08.11

** compiled with: gcc -o client client.c

* tested on: ubuntu 11.04 lts

* gcc version: 4.5.2**/

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define server_port 20000

void

usage(

char

*name)  

intmain(

intargc, 

char

**argv)  

if((client_fd = socket(af_inet, sock_stream, 0)) < 0)  

srand(time(null));  

bzero(&client_addr, sizeof

(client_addr));  

client_addr.sin_family = af_inet;  

client_addr.sin_addr.s_addr = htons(inaddr_any);  

bzero(&server_addr, sizeof

(server_addr));  

server_addr.sin_family = af_inet;  

inet_aton(argv[1], &server_addr.sin_addr);  

server_addr.sin_port = htons(server_port);  

if(connect(client_fd, (

struct

sockaddr*)&server_addr, socklen) < 0)  

return

0;  

}  

編譯完成之後執行:

[cpp]view plain

copy

zhou@neptune:~/data/source$ ./client 88.88.88.88  

此時程式會在connect函式中阻塞等待,約180秒之後輸出:

[cpp]view plain

copy

can not connect to 88.88.88.88, exit!  

connection timed out  

此刻connect的返回值為etimeout。

在此過程中我們可以用netstat命令查詢連線狀態:

[cpp]view plain

copy

zhou@neptune:~/data/source$ sudo netstat -natp |grep 20000  

tcp        0      1 192.168.0.4:44203       88.88.88.88:20000       syn_sent    5954/client      

可以看到此時的tcp連線狀態為syn_sent,也就意味著傳送了syn包之後一直未得到服務端回饋syn ack包。

接下來我們使用這個客戶端程式來連線自己的機器,測試時我的ip位址是192.168.0.4,是乙個無線區域網,結果如下:

[cpp]view plain

copy

zhou@neptune:~/data/source$ ./client 192.168.0.4  

can not connect to 192.168.0.4, exit!  

connection refused  

因為我的機器上並沒有跑在指定埠(20000)上監聽的服務端程式,所以這個連線直接被協議棧拒絕(通過傳送rst型別的tcp包),connect立刻返回,返回值為econnrefused。

再來看看去連線同一區域網中一台不存在的主機時的情形,比如這台想象的主機的ip位址為192.168.0.188:

[cpp]view plain

copy

zhou@neptune:~/data/source$ ./client 192.168.0.188  

can not connect to 192.168.0.188, exit!  

no route to host  

因為本地區域網中的該主機並不存在,arp請求得不到回應,閘道器會回應主機不可達的icmp報文,connect返回ehostunreach。

至此connect函式的分析就結束了,由於本人水平有限,部落格中的不妥或錯誤之處在所難免,殷切希望讀者批評指正。同時也歡迎讀者共同**相關的內容,如果樂意交流的話請留下您寶貴的意見,謝謝。

linux網路程式設計之udp的connect趣談

對於linux網路程式設計,udp協議不是面向連線的協議,直接把資料報傳送到鏈路層,至於能不能到達目的ip和埠,它不關注 大部分時候再編寫 時候只需要在sendto函式中指定你要傳送的埠和ip位址就可以了,不用繫結ip和埠。不過你是否考慮過,udp到底是否可以進行connect,如果對udp進行co...

Linux網路程式設計

linux網路程式設計 當然,我們現在,將要開始編寫的第乙個網路程式,雖然非常簡單,但是卻可以很 清楚的說明大部分編寫網路程式需要的基本概念,好了先讓我們看看網路程式的tcp服 務器端的編寫步驟 1.和伺服器的步驟一樣。2.通過設定套介面位址結構,我們說明,客戶端要與之通訊的伺服器的ip位址和 埠。...

linux 網路程式設計

當然,我們現在,將要開始編寫的第乙個網路程式,雖然非常簡單,但是卻可以很 清楚的說明大部分編寫網路程式需要的基本概念,好了先讓我們看看網路程式的tcp服 務器端的編寫步驟 現在讓我們來看看網路程式客戶端的程式設計步驟 以上的步驟,是比較普遍的,我們可以從中看出,編寫網路程式是很有意思的,同 時,也不...