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