freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

基于64核下tcpip協(xié)議棧的實(shí)現(xiàn)-資料下載頁(yè)

2025-05-12 22:11本頁(yè)面
  

【正文】 000*()+usec) return 0。 } 代碼中涉及到三個(gè)檢查函數(shù),如下: int check_read ( int fd ) int check_write ( int fd ) int check_expr ( int fd ) 函數(shù) check_read 檢查套接字 fd 的是不是有數(shù)據(jù)包可以接收,我們將調(diào)用一次 NetIO 進(jìn)行收包,然后對(duì)數(shù)據(jù)包進(jìn)行判斷,是不是該套接字,如果是就放入其緩沖隊(duì)列,并返回成功;函數(shù) check_write用來(lái)檢查套接字是否可寫,一般是查看套接字的發(fā)送隊(duì)列是不是有空 閑的空間,在本協(xié)議棧中,數(shù)據(jù)發(fā)送緩沖是由 NetIO 進(jìn)行維護(hù)的,因此我們只是簡(jiǎn)單的對(duì)套接字的合法性進(jìn)行判斷;函數(shù) check_expr用來(lái)檢查套接字是不是存在異常,這里我們只要檢查套接字表項(xiàng)中的錯(cuò)誤信息編號(hào)是不是為 0 來(lái)判斷。 關(guān)于 select 如何進(jìn)行非阻塞調(diào)用,我們將在后面與其它函數(shù)配合講解。 建立連接 —— connect 函數(shù) ( 1) 函數(shù)原型 int connect (int fd , struct sockaddr * serv_addr , int addrlen ) 函數(shù) connect 用來(lái)與對(duì) 方(一般成為服務(wù)器)進(jìn)行連接,服務(wù)器信息由參數(shù)二 serv_addr 指定。 connect函數(shù)可能會(huì)被 2 種協(xié)議的套接字調(diào)用: ① 、 TCP 協(xié)議調(diào)用 connect。眾所周知, TCP 協(xié)議是面向連接的,在 TCP 通信前,需要先進(jìn)行三次握手來(lái)完成連接。當(dāng)套接字是 TCP 協(xié)議時(shí),其調(diào)用 connect 函數(shù)將于服務(wù)器完成三次握手的過(guò)程,連接建立之后,才能與服務(wù)器進(jìn)行 TCP 通信。 ② 、 UDP 協(xié)議調(diào)用 connect。盡管 UDP 是面向無(wú)連接的,但是 UDP 協(xié)議的 connect 調(diào)用仍然是有意義的。 UDP 協(xié)議在調(diào)用 connect 函數(shù)時(shí),并不會(huì)進(jìn)行三次 握手,內(nèi)核只是簡(jiǎn)單的對(duì)服務(wù)器的 IP 地址和端口信息進(jìn)行一個(gè)合法性檢查,然后將其保存在套接字表項(xiàng)中。這樣后面在進(jìn)行 14 UDP 通信時(shí),就可以直接調(diào)用 send 和 recv 進(jìn)行收發(fā)包,不用再使用 sendto 和 recvfrom 來(lái)指定服務(wù)器的地址信息。 ( 2) TCP 狀態(tài)機(jī) 在 TCP 連接中,本質(zhì)上不存在所謂的客戶端和服務(wù)端( TCP 是全雙工通信)。我們一般將主動(dòng)發(fā)起連接建立的應(yīng)用進(jìn)程稱為客戶( client) ,而被動(dòng)等待連接建立的應(yīng)用進(jìn)程稱為服務(wù)器( server)。如下圖 41 描述了 TCP 連接的建立和釋放過(guò)程。 圖 41 TCP 連接的建立和釋放 [14] 圖 41 清楚的描述了整個(gè) TCP 連接的生命周期。從建立連接開(kāi)始, TCP 協(xié)議的通信雙方就必須要維持一個(gè)確認(rèn)號(hào) ack 和序列號(hào) seq 來(lái)保證 TCP 的可靠通信,正是這類似于一問(wèn)一答、互通有無(wú)的通信方式,才保證了 TCP 通信的可靠交付。 在 TCP 連接中,可能會(huì)存在通信的雙方同時(shí)發(fā)起或終止連接的情況,盡管其發(fā)生的可能性極少。如果通信雙方都知道對(duì)方的地址信息和端口號(hào),當(dāng)雙方都發(fā)送一個(gè) SYN,并且都被對(duì)方收到時(shí),這就被稱為同時(shí)打開(kāi)( simultaneous open)。類似的, TCP 協(xié)議也允許通信雙方同時(shí)關(guān)閉( simultaneous close)。TCP 的特意設(shè)計(jì)是為了可以處理同時(shí)打開(kāi),對(duì)于同時(shí)打開(kāi)它僅建立一條連接而不是兩條連接。對(duì)于同時(shí)打開(kāi)或關(guān)閉, TCP 連接的建立和釋放過(guò)程就和上圖 41 有所不同,這里我不再畫出其狀態(tài)變遷情況。下面我們僅給出 TCP 連接一個(gè)總的有限狀態(tài)機(jī)(圖 42)。圖中,每個(gè)框表示 TCP 可能的狀態(tài),狀態(tài)之間的箭頭表示可能發(fā)生的狀態(tài)變遷,箭頭旁邊的文字,表明該變遷的原因或者變遷后的動(dòng)作。 CLOSED CLOSED SYN seq=x SYN+ACK seq=y ack=x+1 ACK seq=x+1 ack=y+1 FIN seq=u ACK seq=v ack=u+1 FIN+ACK seq=w ack=u+1 ACK seq=u+1 ack=w+1 建立連接 釋放連接 CLOSED SYN SENT CLOSED LISTEN SYN RCVD ESTAB LISHED CLOSE WAIT LAST ACK ESTAB LISHED FIN WAIT1 FIN WAIT2 TIME WAIT 客戶 服務(wù)器 數(shù)據(jù)傳送 15 圖 42 TCP 有限狀態(tài)機(jī) 函數(shù) connect 在整個(gè) TCP 通信中只參與了建立連接三次握手中客戶方的工作,即圖 42 中狀態(tài) 0至 3 的流程。我們?cè)趯?shí)現(xiàn) connect 函數(shù)的時(shí)候,采用了分層的結(jié)構(gòu),分為四層:應(yīng)用層、 BSD socket層、網(wǎng)絡(luò)層和傳輸層。應(yīng)用層就是為用戶提供調(diào)用接口函數(shù) connect,另外三層函數(shù)申明如下: int sock_connect ( int fd , struct sockaddr * uservaddr , int addrlen ) int i_connect ( struct GK_socket * sock , struct sockaddr * uaddr , int addr_len , int flags ) int tcp_connect (struct GK_socket * sock , struct sockaddr_in * usin , int addr_len ) 函數(shù) sock_connect 被用戶接口函數(shù) connect 調(diào)用,主要是對(duì)套接字表項(xiàng)的狀態(tài)進(jìn)行檢查判斷,對(duì)于還未連接或者連接中的套接字,將調(diào)用 i_connect 函 數(shù)。函數(shù) i_connect 將對(duì)套接字的協(xié)議類型進(jìn)行檢查。對(duì)于 UDP 協(xié)議就記錄服務(wù)器地址信息和端口號(hào),不發(fā)起三次握手;對(duì)于 TCP 協(xié)議則調(diào)用等待發(fā)包 判斷主被動(dòng) 0 1 2 4 發(fā)送 SYN 收到 SYN+ACK/SYN 未收到 SYN+ACK 發(fā)送 ACK 發(fā)送 FIN 5 6 發(fā)送 FIN+ACK 收到 FIN 收到 SYN+ACK/SYN 被動(dòng)連接 收到 SYN 9 13 8 7 12 11 未收到 ACK 收包 發(fā)送 ACK 收到 FIN+ACK 10 發(fā)送 SYN+ACK 等待 2SML 發(fā)送 ACK 收到 ACK 未收到 ACK 主動(dòng)連接 3 收到 ACK 發(fā)包 收到 ACK 還有包 未收到 ACK 收到 FIN+ACK 收到 SYN 或 未收到 ACK 14 15 收到 ACK 16 tcp_connect 發(fā)起三次握手。 tcp_connect 首先發(fā)送一個(gè) SYN 包請(qǐng)求建立連接,然后根據(jù)服務(wù)器返回的數(shù)據(jù)包來(lái)判斷連接是否建立成功: ① 、 如果服務(wù)器返回 SYN/ACK 應(yīng)答包,則表示對(duì)方同意建立連接,回復(fù)對(duì)方一個(gè) ACK 確認(rèn); ② 、 如果服務(wù)器返回 RST/ACK 應(yīng)答包,則表示對(duì)方拒絕建立連接,返回錯(cuò)誤信息連接被拒絕; ③ 、 如果在規(guī)定的時(shí)間內(nèi),服務(wù)器沒(méi)有任何回應(yīng),則認(rèn)為連接超時(shí) ,返回錯(cuò)誤信息連接超時(shí)。 ( 3)非阻塞的 connect 如果在調(diào)用 connect 之前,我們先用函數(shù) ftl 將套接字設(shè)置為非阻塞模式 ,那么調(diào)用 connect 將不會(huì)等待三次握手完成就會(huì)立刻返回。 connect 函數(shù)在發(fā)送 SYN 數(shù)據(jù)包請(qǐng)求建立連接后,會(huì)判斷當(dāng)前套接字是不是阻塞模式,如果是阻塞模式就會(huì)立刻返回,剩下的工作交由內(nèi)核去完成。注意,在這種情形下, connect 的返回值是 1,如果查看套接字的錯(cuò)誤信息,里面記錄的一般就是連接處理中,因此我們不能簡(jiǎn)單的認(rèn)為 connect 返回 1就表示連接失敗或函數(shù)執(zhí)行遇 到錯(cuò)誤。 這時(shí)候,應(yīng)用程序可以去干其它的事情,等一會(huì)后,再調(diào)用 select 對(duì)該套接字進(jìn)行查詢,查詢有三種結(jié)果: ① 、 套接字只能可寫。可寫表示可以發(fā)送數(shù)據(jù),這就表明連接成功。 ② 、 套接字即可寫又可讀??勺x表示接收緩沖區(qū)有數(shù)據(jù),這里要分為兩種情況:數(shù)據(jù)是服務(wù)器發(fā)送的連接反饋信息( RST/ACK),服務(wù)器拒絕連接;數(shù)據(jù)是服務(wù)器發(fā)送的正常數(shù)據(jù)包,連接建立后,服務(wù)器立即就跟我們通信了。因此,遇到這種情況需要調(diào)用 getsockopt 或者查看 errno來(lái)判斷。 ③ 、 其他任何情況,包括套接字異常、套接字只能可讀、超時(shí)等等。這些情況就 是連接失敗了。 本協(xié)議棧在實(shí)現(xiàn)的過(guò)程中,并沒(méi)有采用多線程或者中斷機(jī)制,因此這里無(wú)法實(shí)現(xiàn)一模一樣的非阻塞 connect。作為折衷,我們對(duì)于非阻塞的 connect 調(diào)用將最多等待 1 秒作為超時(shí)等待時(shí)間。因而,我們的 connect 如果返回 1,則肯定表明連接失敗了,錯(cuò)誤信息可以通過(guò) getsockopt 判斷,這也是進(jìn)行非阻塞 connect 編程的模式,因而基本上保證了與非阻塞的 connect 函數(shù)一致的效果,只是在執(zhí)行效率上要低些。 傳送數(shù)據(jù) —— sendto、 send 函數(shù) sendto 函數(shù) ( 1) 函數(shù) 原型 int sendto ( int fd , unsigned char * buf , int len , int flags , struct sockaddr * to , int tolen ) 函數(shù) sendto 參數(shù)二 buf 是將要發(fā)送數(shù)據(jù)包的數(shù)據(jù)部分;參數(shù)三 len 是 buf 的字節(jié)長(zhǎng)度;參數(shù)四 flags是對(duì) sendto 發(fā)送數(shù)據(jù)的一些標(biāo)記信息,一般設(shè)置為 0;參數(shù)五 to 是服務(wù)器的地址信息和端口;參數(shù)六是該結(jié)構(gòu)體的長(zhǎng)度,用來(lái)分辨出 AF_INET 和 AF_PACKET 地址族類型。 sendto 函數(shù)在執(zhí)行 的時(shí)候,根據(jù)套接字類型來(lái)判斷要組裝什么數(shù)據(jù)包并發(fā)送。 ① 、 原始套接字( SOCK_RAW)。對(duì)于原始套接字,用戶必須將 MAC 頭部和 IP 頭部都封裝好,sendto 至多根據(jù)協(xié)議類型(原始 IP 協(xié)議 IPPROTO_RAW)為數(shù)據(jù)包加上 MAC 頭。 ② 、 數(shù)據(jù)報(bào)套接字( SOCK_DGRAM)。數(shù)據(jù)報(bào)套接字的協(xié)議類型一般為 UDP 協(xié)議。該類型套接字用戶只需要提供數(shù)據(jù)負(fù)載即可,剩下的 UDP 頭部、 IP 頭部和 MAC 頭部數(shù)據(jù)都需要 sendto來(lái)完成。 ③ 、 數(shù)據(jù)流套接字( SOCK_STREAM)。數(shù)據(jù)流套接字的協(xié)議類型一般為 TCP 協(xié)議。該類型套接字 用戶也只提供數(shù)據(jù)負(fù)載,剩下的 TCP 頭部、 IP 頭部和 MAC 頭部都需要 sendto 來(lái)完成。 第①、②兩種情況都比較容易處理,對(duì)于第③種情況,發(fā)送 TCP 數(shù)據(jù)前,先要判斷該套接字是否已經(jīng)完成了三次握手建立連接,然后還要根據(jù)通信雙方約定好的序列號(hào)和確認(rèn)號(hào)對(duì) TCP 頭部進(jìn)行填充。 在組裝各類包頭部信息的時(shí)候,我們有用到以下幾個(gè)函數(shù): unsigned int eth_build ( unsigned char * buf , unsigned char * srcMAC , unsigned char * dstMAC , 17 unsigned short proto ) unsigned int ip_build ( unsigned char * buf , unsigned long source , unsigned long victim , unsigned char ttl , unsigned short ipid , unsigned char tos , unsigned char df , unsigned char * ipopt , int ipoptlen , int packetlen , unsigned char proto ) unsigned int tcpip_build ( unsigned char * buf , unsigned long source , unsigned long victim , unsigned char ttl , unsigned short ipid , unsigned char tos , unsigned char df , unsigned char * ipopt , int ipoptlen , unsigned short sport , unsigned short dport , unsigned long seq , unsigned long ack , unsigned char reserved , char flags , unsigned short window , unsigned short urp , unsigned char * tcpopt , int tcpoptlen , unsigned char * data , unsigned short datalen ) unsigned int udpip_build( unsigned char * buf , unsigned long source , unsigned long victim ,
點(diǎn)擊復(fù)制文檔內(nèi)容
范文總結(jié)相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1