1. 程式人生 > >LINUX環境併發伺服器的三種實現模型

LINUX環境併發伺服器的三種實現模型

伺服器設計技術有很多,按使用的協議來分有TCP伺服器和UDP伺服器。按處理方式來分有迴圈伺服器和併發伺服器。

1  迴圈伺服器與併發伺服器模型

在網路程式裡面,一般來說都是許多客戶對應一個伺服器,為了處理客戶的請求,對服務端的程式就提出了特殊的要求。

目前最常用的伺服器模型有:

·迴圈伺服器:伺服器在同一時刻只能響應一個客戶端的請求

·併發伺服器:伺服器在同一時刻可以響應多個客戶端的請求

1.1 UDP迴圈伺服器的實現方法:

UDP迴圈伺服器每次從套接字上讀取一個客戶端的請求->處理->然後將結果返回給客戶機。

因為UDP是非面向連線的,沒有一個客戶端可以老是佔住服務端。只要處理過程不是死迴圈,伺服器對於每一個客戶機的請求總是能夠滿足。

UDP迴圈伺服器模型為:

socket(...);

bind(...);

while(1)
{

   recvfrom(...);

   process(...);

   sendto(...);
}

1.2 TCP迴圈伺服器的實現方法

TCP迴圈伺服器接受一個客戶端的連線,然後處理,完成了這個客戶的所有請求後,斷開連線。TCP迴圈伺服器一次只能處理一個客戶端的請求,只有在這個客戶的所有請求滿足後,伺服器才可以繼續後面的請求。如果有一個客戶端佔住伺服器不放時,其它的客戶機都不能工作了,因此,TCP伺服器一般很少用迴圈伺服器模型的

TCP迴圈伺服器模型為:

socket(...);

bind(...);

listen(...);

while(1)
{

   accept(...);

   process(...);

   close(...);
}

2 三種併發伺服器實現方法

一個好的伺服器,一般都是併發伺服器。併發伺服器設計技術一般有:多程序伺服器、多執行緒伺服器、I/O複用伺服器等。

2.1 多程序併發伺服器

在Linux環境下多程序的應用很多,其中最主要的就是網路/客戶伺服器。多程序伺服器是當客戶有請求時 ,伺服器用一個子程序來處理客戶請求。父程序繼續等待其它客戶的請求。這種方法的優點是當客戶有請求時 ,伺服器能及時處理客戶 ,特別是在客戶伺服器互動系統中。對於一個 TCP伺服器,客戶與伺服器的連線可能並不馬上關閉 ,可能會等到客戶提交某些資料後再關閉 ,這段時間伺服器端的程序會阻塞 ,所以這時作業系統可能排程其它客戶服務程序。比起迴圈伺服器大大提高了服務效能。

TCP多程序併發伺服器

TCP併發伺服器的思想是每一個客戶機的請求並不由伺服器直接處理,而是由伺服器建立一個子程序來處理。

socket(...);

bind(...);

listen(...);

while(1)
{

   accpet(...);

   if(fork(...) == 0)
   {

    process(...);

    close(...);

    exit(...);
   }
   close(...);
}

2.2多執行緒伺服器

多執行緒伺服器是對多程序的伺服器的改進 ,由於多程序伺服器在建立程序時要消耗較大的系統資源 ,所以用執行緒來取代程序 ,這樣服務處理程式可以較快的建立。據統計 ,建立執行緒與建立程序要快 10100 倍 ,所以又把執行緒稱為“輕量級”程序。執行緒與程序不同的是:一個程序內的所有執行緒共享相同的全域性記憶體、全域性變數等資訊。這種機制又帶來了同步問題。以下是多執行緒伺服器模板:

socket(...);

bind(...);

listen(...);

while(1)
{

   accpet(...);

   if((pthread_create(...))!==-1)
   {

     process(...);

     close(...);

     exit(...);
   }
   close(...);
}

2.3 I/O複用伺服器

I/ O複用技術是為了解決程序或執行緒阻塞到某個 I/ O系統呼叫而出現的技術 ,使程序不阻塞於某個特定的I/ O系統呼叫。它也可用於併發伺服器的設計,常用函式select或 poll來實現。

socket(...);

bind(...);

listen(...);

while(1)
{

  if(select(...)>0)

   if(FD_ISSET(...)>0)

        {

accpet(...);

            process(...);

}

   close(...);
}

以上都是TCP伺服器端的程式,TCP客戶端的程式可以通用:

socket(...);

connect(...);

listen(...);

process(...);

close(...);