本發(fā)明涉及數(shù)據(jù)通信領(lǐng)域,特別涉及一種服務(wù)器的socket加密通信方法。
背景技術(shù):
現(xiàn)有技術(shù)中,服務(wù)器的通信方法包括單工通信、半雙工通信和全雙工通信三種。單工通信是指消息只能單方向傳輸?shù)墓ぷ鞣绞?。半雙工通信可以實(shí)現(xiàn)雙向的通信,但不能在兩個方向上同時進(jìn)行,必須輪流交替地進(jìn)行。全雙工通信是指在通信的任意時刻,允許數(shù)據(jù)同時在兩個方向上傳輸。但是,一般的通信方法在速度、效率和安全性方面并不理想。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明提供了一種服務(wù)器的socket加密通信方法,解決了現(xiàn)有技術(shù)的通信方法在速度、效率以及安全性方面并不理想的技術(shù)問題。
本發(fā)明解決上述技術(shù)問題的技術(shù)方案如下:一種服務(wù)器的socket加密通信方法,包括:
s1、啟動新線程,根據(jù)預(yù)定參數(shù)創(chuàng)建服務(wù)器的socket處理器對象,同時啟動新線程創(chuàng)建socket連接監(jiān)視器對象,所述預(yù)定參數(shù)包括:服務(wù)類型、監(jiān)聽地址、監(jiān)聽端口、連接設(shè)定參數(shù)、消息格式變換處理類以及消息處理器;
s2、在所述socket處理器對象中,創(chuàng)建服務(wù)器socket通道對象、服務(wù)器socket連接對象和事件選擇器,并將所述服務(wù)器socket通道對象設(shè)置為非阻塞模式,將所述服務(wù)器socket連接對象與所述監(jiān)聽地址和所述監(jiān)聽端口進(jìn)行綁定;
s3、在所述事件選擇器中,為所述服務(wù)器socket通道對象注冊客戶端請求連接事件;
s4、啟動新線程,根據(jù)所述服務(wù)器socket通道對象、所述服務(wù)器socket對象和所述事件選擇器創(chuàng)建并啟動服務(wù)器socket運(yùn)行對象,接收第一客戶端發(fā)送的連接請求事件,生成第一socket連接對象、所述第一socket通道對象和ssl引擎,與所述第一客戶端建立socket連接;
s5、連接成功后,通過所述第一socket連接對象、所述第一socket通道對象和所述ssl引擎與所述第一客戶端進(jìn)行數(shù)據(jù)交互,同時將所述第一socket連接對象添加到所述socket連接監(jiān)視器對象的socket連接監(jiān)視列表中,以對所述第一socket連接對象的連接狀態(tài)進(jìn)行監(jiān)視。
本發(fā)明的有益效果是:相比現(xiàn)有的通信方法,本技術(shù)方案通過在服務(wù)器為客戶端生成socket通道對象、socket連接對象和ssl引擎,與服客戶端建立socket連接和數(shù)據(jù)交互,不僅提高了數(shù)據(jù)交互的速度和效率,還大大提高了數(shù)據(jù)交互的安全性。
在上述技術(shù)方案的基礎(chǔ)上,本發(fā)明還可以做如下改進(jìn)。
優(yōu)選地,步驟s4中,接收第一客戶端發(fā)送的連接請求事件,生成第一socket連接對象、所述第一socket通道對象和ssl引擎,與所述第一客戶端建立socket連接的方法包括:
a1、當(dāng)所述服務(wù)器socket通道對象接收到所述第一客戶端發(fā)送的連接請求事件時,將所述連接請求事件報(bào)告給所述事件選擇器;
a2、當(dāng)所述事件選擇器接收到所述連接請求事件時,創(chuàng)建第一socket連接對象和第一socket通道對象,生成第一連接id,將所述第一socket通道對象作為所述第一socket連接對象的通信通道;
a3、根據(jù)所述連接設(shè)定參數(shù)中的ssl信息創(chuàng)建并初始化ssl上下文對象,根據(jù)所述ssl上下文對象創(chuàng)建ssl引擎;
a4、通過所述第一socket通道對象、所述第一socket連接對象和所述ssl引擎與所述第一客戶端建立socket連接。
優(yōu)選地,步驟s5中,連接成功之后,通過所述第一socket連接對象、所述第一socket通道對象和所述ssl引擎與所述第一客戶端進(jìn)行數(shù)據(jù)交互之前,還包括:
b1、在所述事件選擇器中為所述第一socket通道對象注冊讀事件,并給所述第一socket通道對象返回讀事件選擇鍵;
b2、將所述讀事件選擇鍵與所述第一socket連接對象的關(guān)系保存到連接對象列表中。
優(yōu)選地,步驟s5中,通過所述第一socket連接對象、所述第一socket通道對象和所述ssl引擎與所述第一客戶端進(jìn)行數(shù)據(jù)交互的方法包括:
c1、當(dāng)所述第一socket通道對象接收到所述第一客戶端發(fā)送的讀請求事件時,將所述讀請求事件報(bào)告給所述事件選擇器,通過所述事件選擇器將所述讀事件選擇鍵放入事件對象集合中;
c2、當(dāng)所述服務(wù)器需要向所述第一客戶端寫入數(shù)據(jù)時,在所述事件選擇器中為所述第一socket通道對象注冊寫事件,并給所述第一socket通道對象返回寫事件選擇鍵;
c3、當(dāng)所述第一socket通道對象與所述第一客戶端的socket通道對象的寫操作準(zhǔn)備就緒時,在所述事件選擇器中生成可寫事件,將所述寫事件選擇鍵放入所述事件對象集合中;
c4、輪詢所述事件對象集合,當(dāng)詢查到所述讀事件選擇鍵時,啟動新線程,處理所述讀事件選擇鍵對應(yīng)的所述讀請求事件,當(dāng)詢查到所述寫事件選擇鍵時,啟動新線程,處理所述寫事件選擇鍵對應(yīng)的所述可寫事件。
優(yōu)選地,步驟c4中,處理所述讀事件選擇鍵對應(yīng)的所述讀請求事件的方法包括:
d1、根據(jù)所述讀事件選擇鍵與所述第一socket連接對象的關(guān)系定位所述第一socket連接對象和所述第一socket通道對象;
d2、判斷所述ssl引擎與所述第一客戶端的ssl引擎是否完成握手,如是則從所述第一socket通道對象中讀取到第一數(shù)據(jù)包,將所述第一數(shù)據(jù)包放入讀數(shù)據(jù)緩沖區(qū),進(jìn)行拆包處理,得到第一數(shù)據(jù)塊,否則進(jìn)行ssl握手處理;
d3、調(diào)用所述消息格式變換處理類的數(shù)據(jù)格式轉(zhuǎn)換方法將所述第一數(shù)據(jù)塊轉(zhuǎn)化為消息格式的第一消息;
d4、調(diào)用所述第一socket連接對象的消息處理方法處理所述第一消息,并通過所述第一socket通道對象將處理結(jié)果發(fā)送給所述第一客戶端的socket通道對象;
優(yōu)選地,步驟d2中,進(jìn)行拆包處理的方法包括:
從所述讀數(shù)據(jù)緩沖區(qū)取出所述第一數(shù)據(jù)包,將所述第一數(shù)據(jù)包的拆包狀態(tài)設(shè)置為未拆包,創(chuàng)建解包數(shù)據(jù)緩沖區(qū);
調(diào)用所述ssl引擎的解包方法,對所述第一數(shù)據(jù)包進(jìn)行解包得到第一數(shù)據(jù)塊,將所述第一數(shù)據(jù)塊放入所述解包數(shù)據(jù)緩沖區(qū),將所述拆包狀態(tài)設(shè)置為已拆包。
優(yōu)選地,步驟c4中,處理所述寫事件選擇鍵對應(yīng)的所述可寫事件的方法包括:
e1、從數(shù)據(jù)緩存區(qū)中讀取到消息格式的第二消息;
e2、調(diào)用所述消息格式變換處理類的數(shù)據(jù)格式轉(zhuǎn)換方法將所述第二消息轉(zhuǎn)化為字節(jié)流格式的第二數(shù)據(jù)塊;
e3、判斷所述ssl引擎與所述第一客戶端的ssl引擎是否完成握手,如是則對所述第二數(shù)據(jù)塊進(jìn)行打包處理,得到第二數(shù)據(jù)包,并將所述第二數(shù)據(jù)包放入寫數(shù)據(jù)緩沖區(qū),然后執(zhí)行步驟e4,否則進(jìn)行ssl握手處理;
e4、從所述寫數(shù)據(jù)緩沖區(qū)中取出所述第二數(shù)據(jù)包,調(diào)用底層的寫數(shù)據(jù)流方法將所述第二數(shù)據(jù)包寫入所述第一socket通道對象中,并通過所述第一socket通道對象發(fā)送到所述第一客戶端的socket通道對象;
優(yōu)選地,步驟e3中,進(jìn)行打包處理的方法包括:
將所述第二數(shù)據(jù)塊的打包狀態(tài)設(shè)置為未打包,創(chuàng)建打包數(shù)據(jù)緩沖區(qū);
調(diào)用所述ssl引擎的打包方法,對所述第二數(shù)據(jù)塊進(jìn)行打包得到第二數(shù)據(jù)包,將所述第二數(shù)據(jù)包放入所述打包數(shù)據(jù)緩沖區(qū),將所述打包狀態(tài)設(shè)置為已打包。
優(yōu)選地,步驟s5中,通過所述socket連接監(jiān)視器對象對所述socket連接監(jiān)視列表中的每個socket連接對象的連接狀態(tài)進(jìn)行監(jiān)視的方法包括:
f1、定時啟動所述socket連接監(jiān)視器對象中的檢查socket連接的任務(wù);
f2、循環(huán)獲取所述socket連接監(jiān)視列表中的每個socket連接對象;
f3、通過每個socket連接對象向?qū)?yīng)的客戶端發(fā)送ping消息,判斷是否接收到應(yīng)答消息,如是則表示該socket連接對象為連接狀態(tài);否則表示該socket連接對象為未連接狀態(tài),刪除該socket連接對象。
優(yōu)選地,步驟s4中,如果接收到多個客戶端發(fā)送的連接請求事件,則為每個客戶端生成各自的socket連接對象和socket通道對象,同時與多個客戶端建立socket連接。
附圖說明
圖1為本發(fā)明實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖2為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖3為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖4為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖5為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖6為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖7為本發(fā)明另一實(shí)施例提供的一種服務(wù)器的socket加密通信方法的流程示意圖;
圖8為本發(fā)明另一實(shí)施例提供的客戶端與服務(wù)器的socket通信過程的示意圖。
具體實(shí)施方式
以下結(jié)合附圖對本發(fā)明的原理和特征進(jìn)行描述,所舉實(shí)例只用于解釋本發(fā)明,并非用于限定本發(fā)明的范圍。
如圖1所示,提供一種服務(wù)器的socket加密通信方法,包括:
s1、啟動新線程,根據(jù)預(yù)定參數(shù)創(chuàng)建服務(wù)器的socket處理器對象,同時啟動新線程創(chuàng)建socket連接監(jiān)視器對象,預(yù)定參數(shù)包括:服務(wù)類型、監(jiān)聽地址、監(jiān)聽端口、連接設(shè)定參數(shù)、消息格式變換處理類以及消息處理器;
s2、在socket處理器對象中,創(chuàng)建服務(wù)器socket通道對象、服務(wù)器socket連接對象和事件選擇器,并將服務(wù)器socket通道對象設(shè)置為非阻塞模式,將服務(wù)器socket連接對象與監(jiān)聽地址和監(jiān)聽端口進(jìn)行綁定;
s3、在事件選擇器中,為服務(wù)器socket通道對象注冊客戶端請求連接事件;
s4、啟動新線程,根據(jù)服務(wù)器socket通道對象、服務(wù)器socket對象和事件選擇器創(chuàng)建并啟動服務(wù)器socket運(yùn)行對象,接收第一客戶端發(fā)送的連接請求事件,生成第一socket連接對象、第一socket通道對象和ssl引擎,與第一客戶端建立socket連接;
s5、連接成功后,通過第一socket連接對象、第一socket通道對象和ssl引擎與第一客戶端進(jìn)行數(shù)據(jù)交互,同時將第一socket連接對象添加到socket連接監(jiān)視器對象的socket連接監(jiān)視列表中,以對第一socket連接對象的連接狀態(tài)進(jìn)行監(jiān)視。
具體地,服務(wù)器先創(chuàng)建socket處理器對象,然后在socket處理器對象中,創(chuàng)建服務(wù)器socket通道對象、服務(wù)器socket連接對象和事件選擇器,為后續(xù)連接作準(zhǔn)備工作,服務(wù)器在接收客戶端發(fā)送的連接請求之前,需要為服務(wù)器socket通道對象在事件選擇器中注冊一個客戶端請求連接事件,在服務(wù)器socket通道對象接收到客戶端發(fā)送的連接請求時,將該連接請求報(bào)告給事件選擇器,事件選擇器為該客戶端生成一個連接id和用于通信的socket連接對象和socket通道對象以及ssl引擎,然后,通過服務(wù)器生成的socket連接對象和socket通道對象以及ssl引擎與客戶端的socket連接對象和socket通道對象進(jìn)行通信。同時,將該socket連接對象添加到socket連接監(jiān)視器對象的socket連接監(jiān)視列表中,通過socket連接監(jiān)視器對象定時對socket連接監(jiān)視列表中的所有socket連接對象進(jìn)行連接檢查,刪除未連接上或失效的對象。
上述實(shí)施例中,網(wǎng)絡(luò)上的兩個程序通過一個雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個連接的一端稱為一個socket。建立網(wǎng)絡(luò)通信連接至少要一對端口號(socket),socket本質(zhì)是編程接口,對tcp/ip的封裝,tcp/ip也要提供可供程序員做網(wǎng)絡(luò)開發(fā)所用的接口,這就是socket編程接口,socket用于描述ip地址和端口,是一個通信鏈的句柄,可以用來實(shí)現(xiàn)不同虛擬機(jī)或不同計(jì)算機(jī)之間的通信。socket非常類似于電話插座。以一個國家級電話網(wǎng)為例,電話的通話雙方相當(dāng)于相互通信的2個進(jìn)程,區(qū)號是它的網(wǎng)絡(luò)地址;區(qū)內(nèi)一個單位的交換機(jī)相當(dāng)于一臺主機(jī),主機(jī)分配給每個用戶的局內(nèi)號碼相當(dāng)于socket號。任何用戶在通話之前,首先要占有一部電話機(jī),相當(dāng)于申請一個socket;同時要知道對方的號碼,相當(dāng)于對方有一個固定的socket。然后向?qū)Ψ綋芴柡艚?,相?dāng)于發(fā)出連接請求(假如對方不在同一區(qū)內(nèi),還要撥對方區(qū)號,相當(dāng)于給出網(wǎng)絡(luò)地址)。假如對方在場并空閑(相當(dāng)于通信的另一主機(jī)開機(jī)且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當(dāng)于連接成功。雙方通話的過程,是一方向電話機(jī)發(fā)出信號和對方從電話機(jī)接收信號的過程,相當(dāng)于向socket發(fā)送數(shù)據(jù)和從socket接收數(shù)據(jù)。通話結(jié)束后,一方掛起電話機(jī)相當(dāng)于關(guān)閉socket,撤消連接。
具體地,如圖2所示,步驟s4中,接收第一客戶端發(fā)送的連接請求事件,生成第一socket連接對象、第一socket通道對象和ssl引擎,與第一客戶端建立socket連接的方法包括:
a1、當(dāng)服務(wù)器socket通道對象接收到第一客戶端發(fā)送的連接請求事件時,將連接請求事件報(bào)告給事件選擇器;
a2、當(dāng)事件選擇器接收到連接請求事件時,創(chuàng)建第一socket連接對象和第一socket通道對象,生成第一連接id,將第一socket通道對象作為第一socket連接對象的通信通道;
a3、根據(jù)連接設(shè)定參數(shù)中的ssl信息創(chuàng)建并初始化ssl上下文對象,根據(jù)ssl上下文對象創(chuàng)建ssl引擎;
a4、通過第一socket通道對象、第一socket連接對象和ssl引擎與第一客戶端建立socket連接。
具體地,服務(wù)器在接收客戶端發(fā)送的連接請求之前,需要為服務(wù)器socket通道對象在事件選擇器中注冊一個客戶端請求連接事件,在服務(wù)器socket通道對象接收到客戶端發(fā)送的連接請求時,將該連接請求報(bào)告給事件選擇器,事件選擇器為該客戶端生成一個連接id和用于通信的socket連接對象、socket通道對象和ssl引擎,然后,通過服務(wù)器生成的socket連接對象、socket通道對象和ssl引擎與客戶端的socket連接對象和socket通道對象進(jìn)行通信。
具體地,如圖3所示,步驟s5中,連接成功之后,通過第一socket連接對象、第一socket通道對象和ssl引擎與第一客戶端進(jìn)行數(shù)據(jù)交互之前,還包括:
b1、在事件選擇器中為第一socket通道對象注冊讀事件,并給第一socket通道對象返回讀事件選擇鍵;
b2、將讀事件選擇鍵與第一socket連接對象的關(guān)系保存到連接對象列表中。
具體地,在服務(wù)器接收客戶端發(fā)送的讀請求之前,需要為第一socket通道對象在事件選擇器中注冊一個感興趣的讀事件,同時事件選擇器給第一socket通道對象返回一個讀事件選擇鍵,在第一socket通道對象接收到客戶端的socket通道對象發(fā)送過來的讀請求時,上報(bào)給事件選擇器,事件選擇器就將第一socket通道對象對應(yīng)的讀事件選擇鍵放入事件對象集合中,事件對象集合中包括需要進(jìn)行處理的讀事件或?qū)懯录W詈?,將讀事件選擇鍵與第一socket連接對象的關(guān)系保存到連接對象列表中,用于后續(xù)根據(jù)讀事件選擇鍵定位第一socket連接對象。
具體地,如圖4所示,步驟s5中,通過第一socket連接對象、第一socket通道對象和ssl引擎與第一客戶端進(jìn)行數(shù)據(jù)交互的方法包括:
c1、當(dāng)?shù)谝籹ocket通道對象接收到第一客戶端發(fā)送的讀請求事件時,將讀請求事件報(bào)告給事件選擇器,通過事件選擇器將讀事件選擇鍵放入事件對象集合中;
c2、當(dāng)服務(wù)器需要向第一客戶端寫入數(shù)據(jù)時,在事件選擇器中為第一socket通道對象注冊寫事件,并給第一socket通道對象返回寫事件選擇鍵;
c3、當(dāng)?shù)谝籹ocket通道對象與第一客戶端的socket通道對象的寫操作準(zhǔn)備就緒時,在事件選擇器中生成可寫事件,將寫事件選擇鍵放入事件對象集合中;
c4、輪詢事件對象集合,當(dāng)詢查到讀事件選擇鍵時,啟動新線程,處理讀事件選擇鍵對應(yīng)的讀請求事件,如圖5所示,包括:
d1、根據(jù)讀事件選擇鍵與第一socket連接對象的關(guān)系定位第一socket連接對象和第一socket通道對象;
d2、判斷ssl引擎與第一客戶端的ssl引擎是否完成握手,如是則從第一socket通道對象中讀取到第一數(shù)據(jù)包,將第一數(shù)據(jù)包放入讀數(shù)據(jù)緩沖區(qū),進(jìn)行拆包處理,得到第一數(shù)據(jù)塊,否則進(jìn)行ssl握手處理;
d3、調(diào)用消息格式變換處理類的數(shù)據(jù)格式轉(zhuǎn)換方法將第一數(shù)據(jù)塊轉(zhuǎn)化為消息格式的第一消息;
d4、調(diào)用第一socket連接對象的消息處理方法處理第一消息,并通過第一socket通道對象將處理結(jié)果發(fā)送給第一客戶端的socket通道對象;
其中,進(jìn)行拆包處理的方法包括:
從讀數(shù)據(jù)緩沖區(qū)取出第一數(shù)據(jù)包,將第一數(shù)據(jù)包的拆包狀態(tài)設(shè)置為未拆包,創(chuàng)建解包數(shù)據(jù)緩沖區(qū);
調(diào)用ssl引擎的解包方法,對第一數(shù)據(jù)包進(jìn)行解包得到第一數(shù)據(jù)塊,將第一數(shù)據(jù)塊放入解包數(shù)據(jù)緩沖區(qū),將拆包狀態(tài)設(shè)置為已拆包。
拆包結(jié)束后,需要對拆包結(jié)果進(jìn)行判斷,如果拆包結(jié)果為“buffer_overflow”,則表示在目標(biāo)緩沖區(qū)沒有足夠的字節(jié)空間可以容納結(jié)果,重新為存儲解包用的數(shù)據(jù)緩沖區(qū)增加緩沖內(nèi)存區(qū)域;如果拆包結(jié)果為“buffer_underflow”,則表示ssl引擎不能對傳入的數(shù)據(jù)解包,因?yàn)闆]有足夠的源字節(jié)可以用來生成一個完整的包;如果拆包結(jié)果為“closed”,則表示關(guān)閉了ssl引擎的這一端,或者由于它已經(jīng)關(guān)閉而無法完成該操作,然后執(zhí)行ssl引擎的closeoutbound方法;如果拆包結(jié)果為“ok”,ssl引擎完成了操作,完成標(biāo)志設(shè)定為true,如果ssl握手操作已經(jīng)完成,并且讀到的數(shù)據(jù)緩沖區(qū)仍然還有未讀完的數(shù)據(jù)的時候,繼續(xù)調(diào)用ssl引擎的解包函數(shù)進(jìn)行處理,否則,獲取解碼后的數(shù)據(jù)緩沖區(qū)的內(nèi)容,并返回其大小,完成標(biāo)志設(shè)定為true。
當(dāng)詢查到寫事件選擇鍵時,啟動新線程,處理寫事件選擇鍵對應(yīng)的可寫事件,如圖6所示,包括:
e1、從數(shù)據(jù)緩存區(qū)中讀取到消息格式的第二消息;
e2、調(diào)用消息格式變換處理類的數(shù)據(jù)格式轉(zhuǎn)換方法將第二消息轉(zhuǎn)化為字節(jié)流格式的第二數(shù)據(jù)塊;
e3、判斷ssl引擎與第一客戶端的ssl引擎是否完成握手,如是則對第二數(shù)據(jù)塊進(jìn)行打包處理,得到第二數(shù)據(jù)包,并將第二數(shù)據(jù)包放入寫數(shù)據(jù)緩沖區(qū),然后執(zhí)行步驟e4,否則進(jìn)行ssl握手處理;
e4、從寫數(shù)據(jù)緩沖區(qū)中取出第二數(shù)據(jù)包,調(diào)用底層的寫數(shù)據(jù)流方法將第二數(shù)據(jù)包寫入第一socket通道對象中,并通過第一socket通道對象發(fā)送到第一客戶端的socket通道對象;
其中,進(jìn)行打包處理的方法包括:
將第二數(shù)據(jù)塊的打包狀態(tài)設(shè)置為未打包,創(chuàng)建打包數(shù)據(jù)緩沖區(qū);
調(diào)用ssl引擎的打包方法,對第二數(shù)據(jù)塊進(jìn)行打包得到第二數(shù)據(jù)包,將第二數(shù)據(jù)包放入打包數(shù)據(jù)緩沖區(qū),將打包狀態(tài)設(shè)置為已打包。
打包結(jié)束后,需要對打包結(jié)果進(jìn)行判斷,如果打包結(jié)果為“buffer_overflow”,則表示在目標(biāo)緩沖區(qū)沒有足夠的字節(jié)空間可以容納結(jié)果,重新為存儲解包用的數(shù)據(jù)緩沖區(qū)增加緩沖內(nèi)存區(qū)域;如果打包結(jié)果為“buffer_underflow”,則表示ssl引擎不能對傳入的數(shù)據(jù)打包,因?yàn)闆]有足夠的源字節(jié)可以用來生成一個完整的包,完成標(biāo)志設(shè)定為true;如果打包結(jié)果為“closed”,則表示關(guān)閉了ssl引擎的這一端,或者由于它已經(jīng)關(guān)閉而無法完成該操作,然后執(zhí)行ssl引擎的closeoutbound方法;如果打包結(jié)果為“ok”,ssl引擎完成了操作,完成標(biāo)志設(shè)定為true,如果寫數(shù)據(jù)緩沖區(qū)還有數(shù)據(jù)的時候,為打包結(jié)果數(shù)據(jù)緩沖區(qū)增加其緩沖內(nèi)存區(qū)域,否則,完成標(biāo)志設(shè)定為true。將打包的數(shù)據(jù)字節(jié)大小返回,并將打包的數(shù)據(jù)寫入到管道。
握手處理過程包括:首先獲取到ssl引擎的當(dāng)前握手狀態(tài);判斷當(dāng)前的狀態(tài),如果狀態(tài)為“not_handshaking”,則表示ssl引擎當(dāng)前沒有進(jìn)行握手,執(zhí)行ssl握手處理;創(chuàng)建一個解包用的讀緩沖區(qū);當(dāng)握手操作沒有完成,并且已經(jīng)不再需要更多數(shù)據(jù)的時候,查詢ssl引擎的當(dāng)前握手狀態(tài),如果狀態(tài)為“not_handshaking”,則表示沒有握手,表示握手操作已經(jīng)完成,握手完成標(biāo)志為true;如果狀態(tài)為“finished”,表示ssl引擎已經(jīng)完成握手,不做任何處理;如果狀態(tài)為“need_task”,表示ssl引擎在繼續(xù)進(jìn)行握手前需要一個(或多個)代理任務(wù)的結(jié)果,獲取該代理任務(wù),并在其他線程中運(yùn)行代理任務(wù);如果狀態(tài)為“need_unwrap”,表示在繼續(xù)進(jìn)行握手前,ssl引擎需要從遠(yuǎn)端接收數(shù)據(jù),執(zhí)行讀數(shù)據(jù)和拆包處理;如果狀態(tài)為“need_wrap”,表示在繼續(xù)進(jìn)行握手前,ssl引擎必須向遠(yuǎn)端發(fā)送數(shù)據(jù),所以應(yīng)該調(diào)用sslengine.wrap(),執(zhí)行打包和寫的處理。最后,將解包用的數(shù)據(jù)讀緩沖區(qū)清空。
具體地,當(dāng)服務(wù)器需要向第一客戶端寫入數(shù)據(jù)時,在事件選擇器中為第一socket通道對象注冊一個寫事件,并給第一socket通道對象返回寫事件選擇鍵,當(dāng)?shù)谝籹ocket通道對象與第一客戶端的socket通道對象的寫操作準(zhǔn)備就緒時,在事件選擇器中生成可寫事件,將寫事件選擇鍵放入事件對象集合中,只有兩邊的通道對象均準(zhǔn)備就緒,才能將數(shù)據(jù)寫入通道對象中??梢钥闯?,處理讀事件選擇鍵對應(yīng)的讀請求事件的過程與處理寫事件選擇鍵對應(yīng)的可寫事件的過程是通過不同線程完成的,兩者可以并行處理,從而提高處理效率。
普通的tcp通信無法保證數(shù)據(jù)的安全,它隨時可能被第三方截獲而泄漏通信雙方之間的隱私,這顯然是我們不希望看到的,尤其在跟用戶名、密碼、個人信息息息相關(guān)的通信過程(如網(wǎng)上銀行交易、機(jī)密文件傳輸?shù)鹊?尤其看重?cái)?shù)據(jù)交互的隱秘性,所以我們常常用ssl協(xié)議來建立安全保密的通信,ssl協(xié)議能夠保證交互雙方的數(shù)據(jù)按密文方式傳輸,第三方在沒有私鑰的情況下幾乎無法破解,從而到達(dá)保密的目的。ssl交互數(shù)據(jù)的過程如下:
1、建立tcp連接
由于ssl協(xié)議依賴于tcp連接實(shí)施,所以在ssl交互之前需要先建立tcp連接??蛻舳薱onnect服務(wù)端,服務(wù)端acccept客戶端,經(jīng)歷三次握手以后tcp連接建立。
2、客戶端發(fā)送ssl請求
客戶端(client)向服務(wù)端(server)發(fā)送自身使用的ssl版本(ssl一共有三個版本)、加密算法的相關(guān)配置、隨機(jī)數(shù)據(jù)以及其在在ssl協(xié)議中需要用到的信息。
3、服務(wù)端處理ssl請求
服務(wù)器(server)反饋給客戶端(client)自己的ssl版本、加密算法的相關(guān)配置、隨機(jī)數(shù)據(jù)以及用自己的私有密鑰加密的server-hello信息。服務(wù)端(server)緊接著將自己的證書(包含公共密鑰)傳遞過去。同時有個可選項(xiàng)目,即服務(wù)端(server)可以要求客服端(client)發(fā)送自己的證書。
4、客戶端驗(yàn)證服務(wù)端身份
客服端(client)用服務(wù)端(server)傳遞過來證書驗(yàn)證服務(wù)端(server)的身份,如果身份未驗(yàn)證通過則結(jié)束本次通信。證書驗(yàn)證通過后利用服務(wù)端(server)的公共密鑰嘗試解開被其用私有密鑰加密過的server-hello信息,如果解開失敗,說明該server-hello必然是假的,故結(jié)束本次通信。
5、客戶端發(fā)送公共密鑰加密過的隨機(jī)數(shù)據(jù)
客戶端端(client)生成隨機(jī)數(shù)據(jù)(sharedsecret),并且把這個隨機(jī)數(shù)據(jù)用服務(wù)端(server)發(fā)送過來的的公共密鑰加密,此次加密過程產(chǎn)生本次握手中的premastersecret(這個步驟是有可能有服務(wù)端的參與的,具體情況由他們使用的加密算法決定),然后將它(premastersecret)送回給服務(wù)端(server)。如果服務(wù)端(server)要求需要驗(yàn)證客戶端(client),那么客服端(client)也需要自己把自己的證書(包含公共密鑰)傳遞過去,同時送一些自己簽過名(私有密鑰加密)的數(shù)據(jù)過去。
6、服務(wù)端用私有密鑰解密加密后的隨機(jī)數(shù)據(jù)并協(xié)商暗號
server驗(yàn)證完client的身份之后,然后用自己的私有密鑰解密得到premastersecret然后雙方利用這個premastersecret來共同協(xié)商,得到mastersecret(可理解為premastersecret為雙方協(xié)商的暗號,然后使用這個暗號再協(xié)商一個mastersecret用來產(chǎn)生真正的會話密鑰用來傳輸數(shù)據(jù))以此來保證數(shù)據(jù)的決對安全。
7、服務(wù)端跟客戶端利用暗號生成加密算法跟密鑰key
雙方用mastersecret一起產(chǎn)生真正的sessionkey,這將是一個對稱加密的key。這個key還可以用來驗(yàn)證數(shù)據(jù)完整性。雙方再交換結(jié)束信息,握手結(jié)束。接下來雙方就可以用協(xié)商好的算法和密鑰key,采用對稱加密算法來通信了。
具體地,如圖7所示,步驟s5中,通過socket連接監(jiān)視器對象對socket連接監(jiān)視列表中的每個socket連接對象的連接狀態(tài)進(jìn)行監(jiān)視的方法包括:
f1、定時啟動socket連接監(jiān)視器對象中的檢查socket連接的任務(wù);
f2、循環(huán)獲取socket連接監(jiān)視列表中的每個socket連接對象;
f3、通過每個socket連接對象向?qū)?yīng)的客戶端發(fā)送ping消息,判斷是否接收到應(yīng)答消息,如是則表示該socket連接對象為連接狀態(tài);否則表示該socket連接對象為未連接狀態(tài),刪除該socket連接對象。
具體地,socket連接監(jiān)視器對象用于定時檢查socket連接對象的連接狀態(tài),刪除未連接或連接失效的socket連接對象。
具體地,步驟s4中,如果接收到多個客戶端發(fā)送的連接請求事件,則為每個客戶端生成各自的socket連接對象和socket通道對象,同時與多個客戶端建立socket連接。如圖8所示,服務(wù)器為每個客戶端在服務(wù)器本地生成一個socket連接對象和socket通道對象,實(shí)現(xiàn)一個服務(wù)器與多個客戶端的通信。
以上所述僅為本發(fā)明的較佳實(shí)施例,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。