1. 程式人生 > >C/S程式的一般流程和基本socket函式(七)

C/S程式的一般流程和基本socket函式(七)

一、基於TCP協議的網路程式


伺服器呼叫socket()、bind()、listen()完成初始化後,呼叫accept()阻塞等待,處於監聽埠的狀態,客戶端呼叫socket()初始化後,呼叫connect()發出SYN段並阻塞等待伺服器應答,伺服器應答一個SYN-ACK段,客戶端收到後從connect()返回,同時應答一個ACK段,伺服器收到後從accept()返回。

資料傳輸的過程:

建立連線後,TCP協議提供全雙工的通訊服務,但是一般的客戶端/伺服器程式的流程是由客戶端主動發起請求,伺服器被動處理請求,一問一答的方式。因此,伺服器從accept()返回後立刻呼叫read(),讀socket就像讀管道

一樣,如果沒有資料到達就阻塞等待,這時客戶端呼叫write()傳送請求給伺服器,伺服器收到後從read()返回,對客戶端的請求進行處理,在此期間客戶端呼叫read()阻塞等待伺服器的應答,伺服器呼叫write()將處理結果發回給客戶端,再次呼叫read()阻塞等待下一條請求,客戶端收到後從read()返回,傳送下一條請求,如此迴圈下去。

如果客戶端沒有更多的請求了,就呼叫close()關閉連線,就像寫端關閉的管道一樣,伺服器的read()返回0,這樣伺服器就知道客戶端關閉了連線,也呼叫close()關閉連線。注意,任何一方呼叫close()後,連線的兩個傳輸方向都關閉,不能再發送資料了。如果一方呼叫shutdown()則連線處於半關閉狀態

,仍可接收對方發來的資料。

在學習socket API時要注意應用程式和TCP協議層是如何互動的: 

*應用程式呼叫某個socket函式時TCP協議層完成什麼動作,比如呼叫connect()會發出SYN段

 *應用程式如何知道TCP協議層的狀態變化,比如從某個阻塞的socket函式返回就表明TCP協議收到了某些段,再比如read()返回0就表明收到了FIN段

補充一下,其實TCP 共有11種狀態,上圖沒有出現的CLOSING 狀態,當雙方同時關閉連線時會出現此狀態,替換掉FIN_WAIT2狀態。

有機狀態圖:
圖中有三種不同的箭頭。粗實線箭頭表示對客戶程序的正常變遷。粗虛線箭頭表示對伺服器程序的正常變遷。

另一種細線箭頭表示異常變遷。


需要注意: TCP 連線必須經過時間 2MSL 後才真正釋放掉。因為:為了保證 A(客戶) 傳送的最後一個 ACK 報文段能夠到達 B(伺服器);防止“已失效的連線請求報文段”出現在本連線中。A 在傳送完最後一個 ACK 報文段後,再經過時間 2MSL(時間等待計時器),就可以使本連線持續的時間內所產生的所有報文段,都從網路中消失。這樣就可以使下一個新的連線中不會出現這種舊的連線請求報文段。

二、基本socket函式

1、socket函式

包含標頭檔案<sys/socket.h>
功能:建立一個套接字用於通訊
原型:int socket(int domain, int type, int protocol);
引數
domain :指定通訊協議族(protocol family),AF_INET、AF_INET6、AF_UNIX等
type:指定socket型別,流式套接字SOCK_STREAM,資料報套接字SOCK_DGRAM,原始套接字SOCK_RAW
protocol :協議型別,IPPROTO_TCP等;一般由前兩個引數就決定了協議型別,設定為0即可。
返回值:成功返回非負整數, 它與檔案描述符類似,我們把它稱為套介面描述字,簡稱套接字。失敗返回-1

2、bind函式

包含標頭檔案<sys/socket.h>
功能:繫結一個本地地址到套接字
原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
引數
sockfd:socket函式返回的套接字
addr:要繫結的地址
addrlen:地址長度
返回值:成功返回0,失敗返回-1

3、listen函式

包含標頭檔案<sys/socket.h>
功能:將套接字用於監聽進入的連線
原型:int listen(int sockfd, int backlog);
引數
sockfd:socket函式返回的套接字
backlog:已完成三次握手的最大連線個數
返回值:成功返回0,失敗返回-1

一般來說,listen函式應該在呼叫socket和bind函式之後,呼叫函式accept之前呼叫。
對於給定的監聽套介面,核心要維護兩個佇列:
1、已由客戶發出併到達伺服器,伺服器正在等待完成相應的TCP三路握手過程
2、已完成連線的佇列

4、accept函式

包含標頭檔案<sys/socket.h>
功能:從已完成連線佇列返回第一個連線,如果已完成連線佇列為空,則阻塞。
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
引數
sockfd:伺服器套接字
addr:將返回對等方的套接字地址
addrlen:返回對等方的套接字地址長度
返回值:成功返回非負整數,失敗返回-1

5、connect函式

包含標頭檔案<sys/socket.h>
功能:建立一個連線至addr所指定的套接字
原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
引數
sockfd:未連線套接字
addr:要連線的套接字地址
addrlen:第二個引數addr長度
返回值:成功返回0,失敗返回-1



相關推薦

C/S程式一般流程基本socket函式

一、基於TCP協議的網路程式 伺服器呼叫socket()、bind()、listen()完成初始化後,呼叫accept()阻塞等待,處於監聽埠的狀態,客戶端呼叫socket()初始化後,呼叫connect()發出SYN段並阻塞等待伺服器應答,伺服器應答一個SYN-AC

C/S程式一般流程基本socket函式

一、基於TCP協議的網路程式 下圖是基於TCP協議的客戶端/伺服器程式的一般流程: 伺服器呼叫socket()、bind()、listen()完成初始化後,呼叫accept()阻塞等待,處於監聽埠的狀態,客戶端呼叫socket()初始化後,呼叫connect()發

C++快速入門---this指標類的繼承10

C++快速入門---this指標和類的繼承(10)   this是一個特殊的指標 class Human {    char fishc;    Human(char fishc); } Human::Human(char

C++快速入門---構造器析構器9

C++快速入門---構造器和析構器(9)   使用面向物件的程式設計技術開發程式最基本步驟: - 定義一個有屬性和方法的類(模板) - 為該類建立一個變數(實現)   構造器和通常方法的主要區別: - 構造器的名字必須和它所在的類的名字一樣 - 系

c 學習體會 使用 ref out 傳遞陣列downmoon

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Problem B: C/C++經典程式訓練2---斐波那契Fibonacci數列

Problem B: C/C++經典程式訓練2---斐波那契(Fibonacci)數列 Time Limit: 1 Sec  Memory Limit: 4 MB Description 編寫計算斐波那契(Fibonacci)數列的第n項函式fib(n)(n&

Problem H: C/C++經典程式訓練2---斐波那契Fibonacci數列

編寫計算斐波那契(Fibonacci)數列的第n項函式fib(n)(n<40): 數列:f1=f2==1; fn=fn-1+fn-2(n>=3)。 Input 輸入整數n的值; Output 輸出fib(n)的值 Sample Input 7 Sampl

c++的靜態多型動態多型筆記

多型(polymorphism)一詞最初來源於希臘語polumorphos,含義是具有多種形式或形態的情形。在程式設計領域,一個廣泛認可的定義是“一種將不同的特殊行為和單個泛化記號相關聯的能力”。和純粹的面向物件程式設計語言不同,C++中的多型有著更廣泛的含義。除了常見

c語言==變數儲存位置堆疊的區別18

明顯的看出全域性變數還有static是儲存在一起的,區域性變數在一起,常數有自己的地方,malloc也是。 從而可以知道虛擬地址空間的分配: 棧空間存放區域性變數,函式形參 堆空間存放malloc,relloc,calloc分配空間、 資料段裡面有B

Linux基本命令總結

進程管理 完整 自己的 mina 緩沖 共享 roc 占用率 linux 接上篇: 33,Linux中的kill命令用來終止指定的進程(terminate a process)的運行,是Linux下進程管理的常用命令。通常,終止一個前臺進程可以使用Ctrl+C鍵,但是,對於

進擊的小白Day017——基於TCP的Socket程式設計完結

在之前的基礎上做了一點優化,程式碼量少了200多行,這次可以跑的通,這個程式終於完成了。不多說,直接貼程式碼。 #define _CRT_SECURE_NO_WARNINGS #pragma comment(lib,"ws2_32.lib") #define PORT 8888 /*定

mysql中的單行函式多行函式講義

--查詢工作為SALESMAN,MANAGER並且工資大於2500的員工資訊 --and關鍵字的執行級別高於or --可以使用小括號提升條件的執行級別,使用了小括號的級別是最高的 select * from emp where (job='SALESMAN' or j

VB6基本資料庫應用:多重條件搜尋

同系列的第七篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/48402835 多重條件搜尋 前文再續,書接上一回。很高興又能說出這句話了。 第五章講述了條件查詢。事實上SQL:Select語句的Where

程式設計師的機器學習入門筆記:推薦系統入門介紹

介紹 背景 隨著網際網路行業的井噴式發展,獲取資訊的方式越來越多,人們從主動獲取資訊逐漸變成了被動接受資訊,資訊量也在以幾何倍數式爆發增長。舉一個例子,PC時代用google reader,常常有上千條未讀部落格更新;如今的微信公眾號,也有大量的紅點未閱

C#進階系列——DDD領域驅動設計初探:Web層的搭建

前言:好久沒更新部落格了,每天被該死的業務纏身,今天正好一個模組完成了,繼續來完善我們的程式碼。之前的六篇完成了領域層、應用層、以及基礎結構層的部分程式碼,這篇打算搭建下UI層的程式碼。 DDD領域驅動設計初探系列文章: 一、UI層介紹 在DDD裡面,UI層的設計也分為BS和CS,本篇還是以Web為

opengl 實體網格繪圖函式基礎

void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);  絲狀球 void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); 實心球void glutWire

Java執行緒多執行緒——ThreadLocal

Java中的ThreadLocal是用來建立執行緒本地變數用的。我們都知道,訪問某個物件的所有執行緒都是能夠共享物件的狀態的,所以這個物件狀態就不是執行緒安全的。開發者可以通過使用同步來保證執行緒安全,但是如果不希望使用同步的話,我們也可以使用ThreadLoc

UINCODE字串安全字串函式

字符集基礎知識 在計算機中,字元都是以二進位制編碼方式存在於儲存中 編碼與解碼 將字元輸入計算機儲存的過程類似於一個”編碼”的過程 而將對應的”編碼”顯示出來的過程類似於一個解碼的過程 二進位制值本身代表什麼含義是可以隨意定義的,在記憶體中用某個2進位制的值代表某一

C++Primer第五版——習題答案詳解

!= filename [1] use ble switch lse prim ++ 習題答案目錄:https://www.cnblogs.com/Mered1th/p/10485695.html 第8章 IO庫 練習8.1 istream &iofunc(is