<b>1、socket通信方式</b>
1.一個Client方連接配接一個Server方,或稱點對點(peer to peer):
2.多個Client方連接配接一個Server方,這也是通常的并發伺服器方式。
3.一個Client方連接配接多個Server方,這種方式很少見,主要用于一個客戶向多個伺服器發送請求情況。
(二)連接配接方式
1.長連接配接
Client方與Server方先建立通訊連接配接,連接配接建立後不斷開,然後再進行封包發送和接收。這種方式下由于通訊連接配接一直存在,可以用下面指令檢視連接配接是否建立:
netstat –f inet|grep 端口号(如5678)。
此種方式常用于點對點通訊。
2.短連接配接
Client方與Server每進行一次封包收發交易時才進行通訊連接配接,交易完畢後立即斷開連接配接。此種方式常用于一點對多點通訊,比如多個Client連接配接一個Server.
(三)發送接收方式
1.異步
封包發送和接收是分開的,互相獨立的,互不影響。這種方式又分兩種情況:
(1)異步雙工:接收和發送在同一個程式中,有兩個不同的子程序分别負責發送和接收
(2)異步單工:接收和發送是用兩個不同的程式來完成。
2.同步
封包發送和接收是同步進行,既封包發送後等待接收傳回封包。同步方式一般需要考慮逾時問題,即封包發上去後不能無限等待,需要設定逾時時間,超過該時間發送方不再等待讀傳回封包,直接通知逾時傳回。
實際通信方式是這三類通信方式的組合。比如一般書上提供的TCP/IP範例程式大都是同步短連接配接的SERVER/CLIENT程式。有的組合是基本不用的,比較常用的有價值的組合是以下幾種:
同步短連接配接Server/Client
同步長連接配接Server/Client
異步短連接配接Server/Client
異步長連接配接雙工Server/Client
異步長連接配接單工Server/Client
其中異步長連接配接雙工是最為複雜的一種通信方式,有時候經常會出現在不同銀行或不同城市之間的兩套系統之間的通信。
<b>2.socket封包處理方式</b>
socket通信封包格式多樣,是以也必須設計對應的讀寫封包的接收和發送封包函數。
(一)阻塞與非阻塞方式
1.非阻塞方式
讀函數不停地進行讀動作,如果沒有封包接收到,等待一段時間後逾時傳回,這種情況一般需要指定逾時時間。
2.阻塞方式
如果沒有封包接收到,則讀函數一直處于等待狀态,直到有封包到達。
(二)循環讀寫方式
1.一次直接讀寫封包
在一次接收或發送封包動作中一次性不加分别地全部讀取或全部發送封包位元組。
2.不指定長度循環讀寫
這一般發生在短連接配接程序中,受網絡路由等限制,一次較長的封包可能在網絡傳輸過程中被分解成了好幾個包。一次讀取可能不能全部讀完一次封包,這就需要循環讀封包,直到讀完為止。
3.帶長度封包頭循環讀寫
這種情況一般是在長連接配接程序中,由于在長連接配接中沒有條件能夠判斷循環讀寫什麼時候結束,是以必須要加長度封包頭。讀函數先是讀取封包頭的長度,再根據這個長度去讀封包.實際情況中,報頭的碼制格式還經常不一樣,如果是非ASCII碼的封包頭,還必須轉換成ASCII,常見的封包頭碼制有:
(1)n個位元組的ASCII碼
(2)n個位元組的BCD碼
(3)n個位元組的網絡整型碼
以上是幾種比較典型的讀寫封包方式,可以與通信方式模闆一起預先提供一些典型的API讀寫函數。當然在實際問題中,可能還必須編寫與對方封包格式配套的讀寫API。在實際情況中,往往需要把我們自己的系統與别人的系統進行連接配接,有了以上模闆與API,可以說連接配接任何方式的通信程式都不存在問題。
伺服器監聽:是伺服器端套接字并不定位具體的用戶端套接字,而是處于等待連接配接的狀态,實時監控網絡狀态。
用戶端請求:是指由用戶端的套接字提出連接配接請求,要連接配接的目标是伺服器端的套接字。為此,用戶端的套接字必須首先描述它要連接配接的伺服器的套接字,指出伺服器端套接字的位址和端口号,然後就向伺服器端套接字提出連接配接請求。
連接配接确認:是指當伺服器端套接字監聽到或者說接收到用戶端套接字的連接配接請求,它就響應用戶端套 接字的請求,建立一個新的線程,把伺服器端套接字的描述發給用戶端,一旦用戶端确認了此描述,連接配接就建立好了。而伺服器端套接字繼續處于監聽狀态,繼續接收其他用戶端套接字的連接配接請求。
<b>系統特殊要求說明</b>
系統采用的是同步短連接配接Server/Client方式,無論Server還是client在封包處理方式上,都采用一次直接讀寫封包+阻塞方式。通信由Client主動發起,一次性發送封包給Server後,主動關閉Socket輸出,伺服器收到Client的關閉輸出響應後,停止socket輸入,并開始處理業務,生成響應封包傳回用戶端。
伺服器處理流程如下:
對于連入的用戶端,伺服器要求其設定連接配接逾時時間、并在輸入資料完成後,主動停止輸出流;如果用戶端沒有主動停止輸出流,則直到連接配接逾時或者關閉輸入流、輸出流和socket時伺服器才會傳回資料。在Java中,主動停止輸出流的函數為socket.shutdownOutput()。
<b>各類語言用戶端關閉輸入輸出流函數說明</b>
<b>1、C語言</b>
<b></b>
int shutdown(int socket,int how)
函數說明 shutdown()用來終止參數s所指定的socket讀取或者傳輸操作,參數how有下列幾種情況:
how=0 終止讀取操作。
how=1 終止傳送操作
how=2 終止讀取及傳送操作
<b>2、php語言</b>
boolean socket_shutdown(resource socket, integer how)
socket_shutdown函數關閉一個socket的輸入輸出。設定how為0則中止接受資料,設定為1則停止發送資料,設定為2則中止二者操作。
<b>3、LoadRunner的Socket協定語言</b>
int lrs_disable_socket ( char *s_desc, int operation );
lrs_disable_socket函數關閉一個socket的輸入輸出。設定operation為SEND則中止接受資料,設定為RECEIVE則停止發送資料,設定為SEND-RECEIVE則中止二者操作。
<b>4、Java語言</b>
socket.shutdownInput():關閉Socket的輸入流;
socket.shutdownOuput():關閉Socket的輸出流。
本文轉自 cuiyingfeng 51CTO部落格,原文連結:http://blog.51cto.com/cuiyingfeng/599825,如需轉載請自行聯系原作者