客戶 伺服器模型

2021-08-21 18:22:13 字數 3736 閱讀 1308

在我們日常所見的網路應用程式中,很多都是由客戶/伺服器(c/s)模型組成的。

伺服器主要承擔著提供資源的責任,通常可以為數量較多的客戶提供服務。

今天我們主要來通過乙個最基本的回射伺服器和客戶端模型的編寫,來體會到客戶和伺服器的角色定位,以及對套接字有更深的理解。

首先要有一些準備知識,了解在linux下的網路程式設計的套接字介面。

socket函式

功能:建立乙個套接字用於程序通訊。套接字在本質上就是乙個檔案描述符。

int socket(int domain, int type, int protocol);

/*domain:指定通訊協議族 //ipv4通常為af_inet

type:指定socket型別,流式套接字sock_stream

(tcp),資料報套接字sock_dgram

(udp),原始套接字sock_raw

protocol:協議型別(如控制傳輸層、網路層或者是鏈路層)

返回值:成功返回非負整數,與檔案描述符類似,稱為套介面描述字,簡稱套接字。失敗返回-1。

*/

bind函式
int bind(int sockfd, const

struct sockaddr* addr, socklen_t addrlen);

/*sockfd:socket函式返回的套接字

addr:要繫結的位址

addrlen:位址長度

返回值:成功返回0,失敗返回-1

*/

listen函式

功能:將套接字用於監聽進入的連線

int listen(int sockfd, int backlog);

/*sockfd:socket函式返回的套接字

backlog:規定核心為此套接字排隊的最大連線個數

返回值:成功返回0,失敗返回-1

*/

使用listen函式之後,套接字就會變成被動套接字,是用來等待連線的,一般用於伺服器。需要繼續呼叫accept函式。

對於給定的監聽套接字介面,核心要維護兩個佇列:

1、已由客戶發出並到達伺服器,伺服器正在等待完成相應的tcp三次握手的過程

2、已經完成連線的佇列

最大連線個數等於已完成連線佇列加上未完成連線的佇列。

accept函式

功能:從已經完成連線佇列返回第乙個連線,如果已完成連線隊列為空,則阻塞。

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

/*sockfd:socket函式返回的伺服器套接字

addr:將返回對等方的套接字位址

addrlen:返回對等方的套接字位址長度

返回值:成功返回0,失敗返回-1

*/

connect函式

功能:建立乙個連線至addr所指定的套接字

int connect(int sockfd, const

struct sockaddr* addr, socklen_t addrlen);

/*sockfd:socket函式返回的未連線的套接字

addr:要連線的套接字位址

addrlen:第二個引數addr的長度

*/

了解完這些基本介面後,還需要知道的是一些套接字的位址結構,如果不了解可以點這裡。

在使用套接字位址的時候記得初始化。

下面是一段常見的套接字初始化的方式。

struct sockaddr_in server;

memset(&server, 0, sizeof(server));

server.sin_family = af_inet;

server.sin_port = htons(atoi(argv[2])); //argv[2]代表由命令列引數傳入的埠號

server.sin_addr.s_addr = inet_addr(argv[1]); //argv[1]代表由命令列引數傳入的ip位址

有了這些知識的準備後,我們很容易就可以編寫乙個基礎的tcp伺服器。**示例如下:

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char* argv)

int sock = socket(af_inet, sock_stream, 0);

if(sock < 0)

struct sockaddr_in server;

memset(&server, 0, sizeof(server));

server.sin_family = af_inet;

server.sin_port = htons(atoi(argv[2]));

server.sin_addr.s_addr = inet_addr(argv[1]);

if(bind(sock, (struct sockaddr*)&server, sizeof(server)) < 0)

if(listen(sock, 10) < 0)

struct sockaddr_in client;

socklen_t len = sizeof(client);

int client_fd;

if((client_fd = accept(sock, (struct sockaddr*)&client, &len)) < 0)

char buf[1024] = ;

while(1)

close(sock);

return

0;}

下面是客戶端的**示例:

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char* argv)

struct sockaddr_in client;

memset(&client, 0, sizeof(client));

client.sin_family = af_inet;

client.sin_port = htons(atoi(argv[2]));

client.sin_addr.s_addr = inet_addr(argv[1]);

if(connect(sock, (struct sockaddr*)&client, sizeof(client)) < 0)

char recvbuf[1024] = ;

char sendbuf[1024] = ;

while(fgets(sendbuf, sizeof(sendbuf), stdin) != null)

close(sock);

return

0;}

這乙份示例**還有很多不完善的地方,如只能接收乙個客戶的請求,在伺服器主動斷開連線後,會進入time_wait狀態等缺點,如果有興趣,可以了解setsockopt函式。

C S模型(客戶 伺服器模型)

c s模型即客戶 client 伺服器 server 模型。1.特點 伺服器提供服務,客戶請求服務。2.客戶端和伺服器之間連線的數量對應關係 多個客戶程序可以同時訪問乙個服務程序,乙個客戶程序可以同時訪問多個伺服器程序提供的服務。3.客戶端和伺服器所在不同網路位置所適用的場合 執行在同乙個機器上的場...

客戶端 伺服器程式設計模型

客戶端和伺服器是程序,不是主機。客戶端 伺服器模型中的基本操作是事務。乙個客戶端 伺服器事務由四步組成 1.當乙個客戶端需要服務時,它向伺服器傳送乙個請求,發起乙個事務。例如,當web瀏覽器需要乙個檔案時,它就傳送乙個請求給web伺服器。2.伺服器收到請求後,解釋它,並以適當的方式操作它的資源。例如...

回射客戶 伺服器模型(1)

最近在學習socket程式設計,根據自己的學習過程及學習筆記,下面來梳理一下如何實現乙個簡單的回射客戶 伺服器模型,也藉此來熟悉一下socket bind listen accept connect這些函式的使用。簡單的回射客戶 伺服器模型 下面先看一下乙個客戶 伺服器模型的框架圖。可以看到,伺服器...