基本TCP套接字程式設計

2021-07-30 10:54:50 字數 3363 閱讀 1620

基本tcp客戶/伺服器程式的套接字函式

返回:若成功則為非負描述符,若則為-1

其中family引數指明協議族,為某個常值。該引數也往往稱為協議域。

family

說明af_inet

ipv4協議

af_inet6

ipv6協議

af_local

unix域協議

af_route

路由套接字

af_key

金鑰套接字

其中type指明套接字的型別,它也是某個常值。

type

說明sock_stream

位元組流套接字

sock_dgram

資料報套接字

sock_seqpacket

有序分組套接字

sock_ram

原始套接字

protocol引數為某個協議的型別常值,或者設為0,以選擇所給定的familytype的系統預設值。並非所有的組合都是有效。有效組合見下圖。

protocol

說明ipproto_tcp

tcp傳輸協議

tpproto_udp

udp傳輸協議

ipproto_sctp

sctp傳輸協議

socket函式中family和type引數的組合

tcp客戶用connect函式建立與tcp伺服器的連線。

#include 

int connect(int sockfd, const

struct sockaddr *servaddr, socklen_t addrlen);

返回: 若成功返回則為0,若出錯則為-1.

如果是tcp套接字,呼叫connect函式 將激發 tcp 的 三次握手,而且僅在鏈結建立成功或者出錯時放回,錯誤返回可能有一下幾種情況。

1. 若tcp客戶沒有收到syn響應,則會返回etimedout錯誤

2. 若對客戶的syn的響應是rst(表示復位),則表明該伺服器主機在我們指定的埠上沒有程序再等待與之連線。這是一種硬錯誤,客戶一接受到,就馬上返回sconnrefused錯誤

3. 若客戶發出的syn在中間的某個路由引發了乙個目的不可達的icmp錯誤,則認為是一種軟錯誤。客戶端會進行重發,一段時間後還是沒有收到相應,則會把儲存的訊息(icmp錯誤)作為ehostunreach或enetunreach錯誤放回給程序。

bind函式把乙個本地協議位址付給乙個套接字。對於網際網協議,協議位址是32位的ipv4位址或者128的ipv6位址與16位的tcp或者udp埠號的組合。

#include 

int bind(int sockfd, const

struct sockaddr *myaddr, socklen_t addrlen)

返回:成功返回0,若出錯則為-1

第二個引數是乙個指向於特定協議的位址結構指標,第三個引數是該位址結構的長度。對於tcp,呼叫bind函式可以指定乙個埠號,或指定乙個ip位址,也可以兩者都指定,也可以兩者都不指定。

本函式通常應該在socket和bind這兩個函式之後,並在呼叫accept之前呼叫。

#include 

int listen(int sockfd, int backlog)

返回: 若成功返回0,若出錯則為-1

listen 函式僅有tcp伺服器呼叫,它做兩件事情。

1. 當socket 函式建立乙個套接字時,它被假設為乙個主動套接字,也就是說,它是乙個將呼叫connect發起連線的客戶套接字。listen函式把乙個未連線的套接字轉換成乙個被動套接字,指示核心應接受指向該套接字的連線請求。

2. 本函式的第二引數規定了核心應該為相應的套接字排隊的最大連線個數。

為理解其中的backlog引數,我們必須認識到核心為任何乙個給定的監聽套接字維護兩個佇列

1. 未完成連線佇列,每個這樣的syn 分節對應其中一項:已由某個客戶發出並到達伺服器,而伺服器正在等待相應的tcp三次握手過程。這些套接字處於syn_rcvd狀態。

2. 已完成連線佇列,每個已經完成tcp三路握手的客戶對應其中一項。這些套接字處於established狀態

accept 函式由tcp伺服器呼叫,用於從已完成連線佇列對頭返回下乙個已完成連線。如果已完成連線隊列為空,那麼程序被投入睡眠(假定套接字為預設的阻塞方式)

#include 

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

返回:若成功則為非負描述符,若出錯則為-1

引數cliaddr和addrlen用來返回已連線的對端程序(客戶)的協議位址。addrlen是值-結果引數。呼叫前,我們將有*addrlen所引用的整數數值設定為有cliaddr所指的套接字位址接受的長度,返回時,該整數值即為由核心存放在該套接字位址結構內的確切位元組數。

如果accept成功,那麼返回值由核心自動生成乙個全新的描述符,代表與所返回客戶的tcp連線。我們稱accept的第乙個引數為監聽套接字。稱它返回的套接字為已連線套接字。乙個伺服器通常僅僅建立乙個監聽套接字,它在該伺服器的生命週期內一直存在。核心為每個由伺服器程序接受的客戶連線建立乙個已連線套接字。當伺服器完成對某個給定客戶的服務時,相應的已連線套接字就被關閉了。

fork 函式是unix中派生新程序的唯一方法

#include 

pid_t fork(void)

返回:在子程序為0,在父程序中為子程序id,若出錯則為-1

通常的 unix close 函式也用來關閉套接字,並終止tcp連線

#include 

int close(int sockfd)

返回:成功0,出錯-1

基本TCP套接字程式設計

經過最近一段時間的系統學習,對於傳輸協議中tcp協議的套接字程式設計以及11中狀態轉化有了一定的認識,現在做出 以下總結 上圖是幾乎所有教科書上關於tcp客戶端 伺服器通訊過程中api函式的彙總。首先看伺服器端 1 服務端以被動連線的方式參與通訊,因此首先呼叫socket int family,in...

基本TCP套接字程式設計

tcp客戶與伺服器程序之間典型事件時間表 socket函式 includeint socket int family,int type,int protocol family引數執行協議族,該引數也往往被稱為協議域。是以下某個常值 type引數指明套接字型別,是以下某個常值 protocol引數應設...

基本TCP套接字程式設計

基本tcp套接字程式設計 connect函式 includeint connect int sockfd,const struct sockaddr servaddr,socklen t addrlen 返回 若成功則為0,若出錯則為 1 客戶端呼叫connect前不必非得呼叫bind函式,因為核心...