全双工多线程套接字通信的研究与实现
2017-06-22舒玉坤张国祥
舒玉坤,张国祥
(1.湖北师范大学 数学与统计学院,湖北 黄石 435002 ; 2.湖北师范大学 物理与电子科学学院,湖北 黄石 435002)
全双工多线程套接字通信的研究与实现
舒玉坤1,张国祥2
(1.湖北师范大学 数学与统计学院,湖北 黄石 435002 ; 2.湖北师范大学 物理与电子科学学院,湖北 黄石 435002)
对网络环境中分布式进程通信的特点分析,借助JAVA对多线程套接字通信的支持,在Android平台下,使用JAVA语言编程实现了全双工多线程套接字通信,该方法安全,快捷,方便,具有一定的实用性。
JAVA; 客户端/服务器; 套接字;多线程;通信
1 网络通信的特点
计算机网络是分布在不同地理位置的多台自治计算机系统的集合,这种自治表现为“独立”,即每台计算机的操作和资源,都由自身的操作系统来管理,用户共享的网络资源通过网络环境中的分布式进程通信来实现;而单机系统中的通信则体现为程序在时间上严格按照次序执行(静态),进程是一个程序对某个数据集的执行过程(动态),要保证通信的正常进行,必须对进程创建、撤销和状态转换进行控制。可见网络进程通信与单机进程通信的本质区别是网络中的主机具有高度的自治性;不同的主机没有一个统一的高层操作系统进行全局控制、调度与管理,因此网络环境下分布式进程通讯需要解决进程命名与寻址方式,多重协议的识别,进程间的相互作用等问题。为此,在UNIX中引入五元组(或一个相关association)即协议、本地地址、本地端口号、远程地址、远程端口号来完整标识一个进程。
2 客户端/服务器(C/S)
在TCP/IP中,进程间相互作用采用客户端/服务器模式,即用client/server分别表示相互通信的两个应用程序的进程,客户向服务器发出服务请求,服务器响应客户的请求,提供客户所需要的服务,由于网络资源分布的不均匀性以及进程通信的异步性,有必要建立一个机制,为进程之间建立连接,在进程交换数据的过程中维护连接,为数据交换提供同步控制与协调。
3 套接字(Socket)
使用TCP/IP协议的应用程序,一般用UNIX BSD的套接字(Socket)来实现网络进程之间的通信,按照UNIX思想就是“一切皆文件”,都可以用“打开”、“读/写”、“关闭”等模式来操作,Socket就是该模式的一个具体实现,是一种特殊的文件,通过socket()、bind()、listen()、connect()、accept()、read()、write()、close()函数来实现。
在网络中应用层可以利用Socket对应的函数建立进程的连接,实现数据交换,因为Socket本身是面向client/server模式设计的,针对客户和服务器的不同程序提供了不同Socket系统调用,客户机可随机申请一个Socket,服务器使用熟知的Socket,客户可以随机向服务器发出请求,服务器提供相应的服务。
4 多线程套接字通信的原理
4.1 JAVA对多线程通信的支持
JAVA是常用的网络编程语言之一,它本身提供了Thread类,封装了有关线程的控制,负责线程的启动运行、休眠、挂起、恢复、退出和终止,以及线程优先级的控制,同时使用管程机制(monitor)来控制JAVA多线程的同步,提供3个标准Object类方法wait()、notify()和notifyAll()来实现线程之间的控制转移,以防止在一个线程已得到了资源,而其它线程无休止的“忙等待”,消耗CPU资源,以解决“死锁”的问题。 为保证客户和服务器的正常连接,Socket通过三次握手来实现连接,如图1所示:
图1 Socket三次握手
从图1中可知,当客户端调用connect()时,触发了连接请求,向服务区发出SYN J包,使connect进入阻塞状态,服务器监听到连接请求后,调用Accept()接收请求,并向客户发送SYN K,ACK J+1,这时Accept进入阻塞状态,客户收到服务器SYN K,ACK j+1后,并对SYN K进行确认,服务器收到ACK k+1时,Accept(返回)三次握手完成,连接建立成功。
4.2 多线程套接通信的实现
一个进程是一个独立的运行环境,可以看作一个程序或者一个应用,而线程是在进程中执行的一个任务,Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程,线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态。多个线程共享堆内存,因此创建多个线程去执行一些任务会比创建多个进程更好。
JAVA有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类,并调用了Thread的run()方法,本文采用第二种方法,在客户端程序中,首先通过mReceiveThread = new ReceiveThread(clientSocket),然后,为了在新的线程中执行,需要使用mReceiveThread.start()开启线程;在服务器程序中,首先通过mAcceptThread = new AcceptThread(),然后使用mAcceptThread.start()开启线程。在Java中新建一个线程时,它的状态是New,当调用线程的start()方法时,状态被改变为Runnable,线程调度器会为Runnable线程池中的线程分配CPU时间并且将它的状态置为Running。当然也可以使用Thread类的Sleep()方法让线程暂停一段时间,但不会让线程终止,一旦从休眠中唤醒线程,线程的状态将会被改变为Runnable,并且根据线程调度,它将得到执行。如图2所示:
图2 客户连接请求与服务器监听请求及信息收发
线程调度是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间,一旦创建一个线程并启动它,它的执行便依赖于线程调度器的实现,CPU分配给可用的Runnable线程时间片,分配CPU时间可以基于线程优先级或者线程等待的时间,线程调度并不受Java虚拟机控制。
在程序实现中需要注意的是,在安卓系统2.3的系统上通信正常,但在4.0以上系统需要附加以下代码,否则出错。
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
程序实现客户与服务器收发信息界面如图3所示:界面为中文繁体,可转换为中文简体,在通信的过程中,为防止信息出现乱码,可通过new String(this.information, "编码方式").trim()进行编码转换,以保证通信的双方编码一致。
图3 客户与服务器收发信息界面
[1]吴功宜. 计算机网络高级教程[M]. 北京:清华大学出版社,2007.
[2]Richard Stevens W. UNIX网络编程(第2版) [M].北京:清华大学出版社,1999.
[3]Andrew S, Tanenbaum. Computer Networks (Third Edition) [M].北京:清华大学出版社,1998.
[4]Sayed Y, Hashimi, Satya Komatineni. 精通Android2[M]. 北京:人民邮电出版社,2010.
[5]吴亚峰,苏亚光.Android应用案例开发大全[M].北京:人民邮电出版社,2011.
[6]张 斌,高 波. Linux网络编程 [M].北京:清华大学出版社,2000.
[7]陈 浩.JAVA编程入门与提高 [M].北京:机械工业出版社,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