舒玉坤,張國祥
(1.湖北師范大學 數(shù)學與統(tǒng)計學院,湖北 黃石 435002 ; 2.湖北師范大學 物理與電子科學學院,湖北 黃石 435002)
全雙工多線程套接字通信的研究與實現(xiàn)
舒玉坤1,張國祥2
(1.湖北師范大學 數(shù)學與統(tǒng)計學院,湖北 黃石 435002 ; 2.湖北師范大學 物理與電子科學學院,湖北 黃石 435002)
對網(wǎng)絡環(huán)境中分布式進程通信的特點分析,借助JAVA對多線程套接字通信的支持,在Android平臺下,使用JAVA語言編程實現(xiàn)了全雙工多線程套接字通信,該方法安全,快捷,方便,具有一定的實用性。
JAVA; 客戶端/服務器; 套接字;多線程;通信
計算機網(wǎng)絡是分布在不同地理位置的多臺自治計算機系統(tǒng)的集合,這種自治表現(xiàn)為“獨立”,即每臺計算機的操作和資源,都由自身的操作系統(tǒng)來管理,用戶共享的網(wǎng)絡資源通過網(wǎng)絡環(huán)境中的分布式進程通信來實現(xiàn);而單機系統(tǒng)中的通信則體現(xiàn)為程序在時間上嚴格按照次序執(zhí)行(靜態(tài)),進程是一個程序?qū)δ硞€數(shù)據(jù)集的執(zhí)行過程(動態(tài)),要保證通信的正常進行,必須對進程創(chuàng)建、撤銷和狀態(tài)轉換進行控制??梢娋W(wǎng)絡進程通信與單機進程通信的本質(zhì)區(qū)別是網(wǎng)絡中的主機具有高度的自治性;不同的主機沒有一個統(tǒng)一的高層操作系統(tǒng)進行全局控制、調(diào)度與管理,因此網(wǎng)絡環(huán)境下分布式進程通訊需要解決進程命名與尋址方式,多重協(xié)議的識別,進程間的相互作用等問題。為此,在UNIX中引入五元組(或一個相關association)即協(xié)議、本地地址、本地端口號、遠程地址、遠程端口號來完整標識一個進程。
在TCP/IP中,進程間相互作用采用客戶端/服務器模式,即用client/server分別表示相互通信的兩個應用程序的進程,客戶向服務器發(fā)出服務請求,服務器響應客戶的請求,提供客戶所需要的服務,由于網(wǎng)絡資源分布的不均勻性以及進程通信的異步性,有必要建立一個機制,為進程之間建立連接,在進程交換數(shù)據(jù)的過程中維護連接,為數(shù)據(jù)交換提供同步控制與協(xié)調(diào)。
使用TCP/IP協(xié)議的應用程序,一般用UNIX BSD的套接字(Socket)來實現(xiàn)網(wǎng)絡進程之間的通信,按照UNIX思想就是“一切皆文件”,都可以用“打開”、“讀/寫”、“關閉”等模式來操作,Socket就是該模式的一個具體實現(xiàn),是一種特殊的文件,通過socket()、bind()、listen()、connect()、accept()、read()、write()、close()函數(shù)來實現(xiàn)。
在網(wǎng)絡中應用層可以利用Socket對應的函數(shù)建立進程的連接,實現(xiàn)數(shù)據(jù)交換,因為Socket本身是面向client/server模式設計的,針對客戶和服務器的不同程序提供了不同Socket系統(tǒng)調(diào)用,客戶機可隨機申請一個Socket,服務器使用熟知的Socket,客戶可以隨機向服務器發(fā)出請求,服務器提供相應的服務。
4.1 JAVA對多線程通信的支持
JAVA是常用的網(wǎng)絡編程語言之一,它本身提供了Thread類,封裝了有關線程的控制,負責線程的啟動運行、休眠、掛起、恢復、退出和終止,以及線程優(yōu)先級的控制,同時使用管程機制(monitor)來控制JAVA多線程的同步,提供3個標準Object類方法wait()、notify()和notifyAll()來實現(xiàn)線程之間的控制轉移,以防止在一個線程已得到了資源,而其它線程無休止的“忙等待”,消耗CPU資源,以解決“死鎖”的問題。 為保證客戶和服務器的正常連接,Socket通過三次握手來實現(xiàn)連接,如圖1所示:
圖1 Socket三次握手
從圖1中可知,當客戶端調(diào)用connect()時,觸發(fā)了連接請求,向服務區(qū)發(fā)出SYN J包,使connect進入阻塞狀態(tài),服務器監(jiān)聽到連接請求后,調(diào)用Accept()接收請求,并向客戶發(fā)送SYN K,ACK J+1,這時Accept進入阻塞狀態(tài),客戶收到服務器SYN K,ACK j+1后,并對SYN K進行確認,服務器收到ACK k+1時,Accept(返回)三次握手完成,連接建立成功。
4.2 多線程套接通信的實現(xiàn)
一個進程是一個獨立的運行環(huán)境,可以看作一個程序或者一個應用,而線程是在進程中執(zhí)行的一個任務,Java運行環(huán)境是一個包含了不同的類和程序的單一進程。線程可以被稱為輕量級進程,線程需要較少的資源來創(chuàng)建和駐留在進程中,并且可以共享進程中的資源。在多線程程序中,多個線程被并發(fā)的執(zhí)行以提高程序的效率,CPU不會因為某個線程需要等待資源而進入空閑狀態(tài)。多個線程共享堆內(nèi)存,因此創(chuàng)建多個線程去執(zhí)行一些任務會比創(chuàng)建多個進程更好。
JAVA有兩種創(chuàng)建線程的方法:一是實現(xiàn)Runnable接口,然后將它傳遞給Thread的構造函數(shù),創(chuàng)建一個Thread對象;二是直接繼承Thread類,并調(diào)用了Thread的run()方法,本文采用第二種方法,在客戶端程序中,首先通過mReceiveThread = new ReceiveThread(clientSocket),然后,為了在新的線程中執(zhí)行,需要使用mReceiveThread.start()開啟線程;在服務器程序中,首先通過mAcceptThread = new AcceptThread(),然后使用mAcceptThread.start()開啟線程。在Java中新建一個線程時,它的狀態(tài)是New,當調(diào)用線程的start()方法時,狀態(tài)被改變?yōu)镽unnable,線程調(diào)度器會為Runnable線程池中的線程分配CPU時間并且將它的狀態(tài)置為Running。當然也可以使用Thread類的Sleep()方法讓線程暫停一段時間,但不會讓線程終止,一旦從休眠中喚醒線程,線程的狀態(tài)將會被改變?yōu)镽unnable,并且根據(jù)線程調(diào)度,它將得到執(zhí)行。如圖2所示:
圖2 客戶連接請求與服務器監(jiān)聽請求及信息收發(fā)
線程調(diào)度是一個操作系統(tǒng)服務,它負責為Runnable狀態(tài)的線程分配CPU時間,一旦創(chuàng)建一個線程并啟動它,它的執(zhí)行便依賴于線程調(diào)度器的實現(xiàn),CPU分配給可用的Runnable線程時間片,分配CPU時間可以基于線程優(yōu)先級或者線程等待的時間,線程調(diào)度并不受Java虛擬機控制。
在程序?qū)崿F(xiàn)中需要注意的是,在安卓系統(tǒng)2.3的系統(tǒng)上通信正常,但在4.0以上系統(tǒng)需要附加以下代碼,否則出錯。
StrictMode.setThreadPolicy(new StrictMode
.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode
.VmPolicy
.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.penaltyDeath()
.build());
同時還要在AndroidManifest.xml中開放以下權限:
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
程序?qū)崿F(xiàn)客戶與服務器收發(fā)信息界面如圖3所示:界面為中文繁體,可轉換為中文簡體,在通信的過程中,為防止信息出現(xiàn)亂碼,可通過new String(this.information, "編碼方式").trim()進行編碼轉換,以保證通信的雙方編碼一致。
圖3 客戶與服務器收發(fā)信息界面
[1]吳功宜. 計算機網(wǎng)絡高級教程[M]. 北京:清華大學出版社,2007.
[2]Richard Stevens W. UNIX網(wǎng)絡編程(第2版) [M].北京:清華大學出版社,1999.
[3]Andrew S, Tanenbaum. Computer Networks (Third Edition) [M].北京:清華大學出版社,1998.
[4]Sayed Y, Hashimi, Satya Komatineni. 精通Android2[M]. 北京:人民郵電出版社,2010.
[5]吳亞峰,蘇亞光.Android應用案例開發(fā)大全[M].北京:人民郵電出版社,2011.
[6]張 斌,高 波. Linux網(wǎng)絡編程 [M].北京:清華大學出版社,2000.
[7]陳 浩.JAVA編程入門與提高 [M].北京:機械工業(yè)出版社,2011.
Research and implementation of full duplex multi-threadedsocket communication
SHU Yu-kun1,ZHANG Guo-xiang2
(1.College of Mathematics and Statistics,Hubei Normal University,Huangshi 435002,China;2. College of Physics and Electronics Science,Hubei Normal University,Huangshi 435002,China;)
Based on the characteristics of distributed interposes communication in network environment, With the help of JAVA support for multithreaded socket communication, using JAVA programming to realize full duplex multithread socket communication in the Android platform, the method is safe, quick, convenient and has a certain practicality.
JAVA; client / server; socket; multi thread; communication
2016—02—25
舒玉坤(1984— ),女,湖南溆浦人,助理實驗師、碩士,主要研究方向為微電子與信息技術.
TP393
A
2096-3149(2017)02- 0005-04
10.3969/j.issn.2096-3149.2017.02.002