一起Talk Android吧(第三百二十五回:Android中网络通信之TCP通信模型二)
Posted talk_8
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起Talk Android吧(第三百二十五回:Android中网络通信之TCP通信模型二)相关的知识,希望对你有一定的参考价值。
各位看官们,大家好,上一回中咱们说的是android中网络通信之TCP通信模型的例子,这一回中咱们继承说该例子。闲话休提,言归正转。让我们一起Talk Android吧!
看官们,我们在上一章回中介绍了TCP通信的迭代模型,本章回将介绍并发模型,也就是多个客户端与多个服务端同时进行TCP通信。因为一个服务器同时与多个客户端通信时会发生响应慢的情况,引入并发模型后可以解决服务器响应慢的问题。下面是该模型的示意图:
只有文字和图像不足以了解并发模型,下面我们通过文字结合代码的方法来介绍迭代模型:
服务端演示
这里使用的服务端和迭代模型中使用的服务端完全相同,因此不再做详细介绍.
客户端演示
这里使用的客户端和迭代模型中使用的客户端完全相同,因此不再做详细介绍.
TCP通信演示
我们创建一个包含main方法的类,用它来当作控制TCP通信的主程序。在main方法中先创建服对象。因为TCP通信过程中会阻塞主线程,也就是main方法所在在线程,所以我们创建了三个子线程,用来表示三个服务端。
在服务端线程中主要是监听客户端发来的连接请求,在接受连接请求后接收客户端发来的数据,接收完特定数据后结束线程。这里的特定数据表示包含ID为2、3、5的客户端发来的数据。这种结束线程的方法和迭代模型中的不同,因为并发模型中没有特定的接收顺序,无法保证某个服务器线程可以接收到最后一个数据,因此添加三个特定数据,这样可以保证结束正常结束。
接着创建五个客户端对象,并且添加到数组中,接着依次调用客户端的startRunning()方法来启动线程,线程启动后,客户端会向服务端发起连接并且发送数据到服务端。这里一共有五个客户端并且每个客户端都对应一个线程,这相当于有五个客户端同时在和服务器进行TCP通信。
我们在客户端向服务端发送的数据是客户端的ID,比如:“Client3”,在程序运行时可以看到。
有两点内容需要引起注意:
- 需要先启动服务端线程后再启动客户端线程;
- 在程序最后关闭TCP连接;
以上是并发模型中所有的程序内容,与迭代模型相比有三点不一样:
- 创建服务端线程的数量由一个变为三个;
- 服务器线程停止的条件也适当放宽;
- 关闭TCP连接的时间。
迭代模型在服务器线程结束时关闭TCP连接,并发模型在程序的最后关闭连接,因为服务器线程有三个,如果这三个线程中的某一个线程结束了就关闭TCP连接会使的另外两个线程无法进行TCP通信,这点需要引起注意,不然会发生异常。下面是该类的代码,请大家参考:
import java.util.ArrayList;
public class TCPEx3
public static void main(String args[])
String serverAddress = "127.0.0.1";
int serverPort = 8009;
T8Server2 mServer;
T8Client2 mClient;
Thread mServerThread;
Thread mClientThread;
ArrayList<T8Client2> clientGroup = new ArrayList<T8Client2>();
ArrayList<Thread> serverThreadGroup = new ArrayList<Thread>();
//create server1
mServer = new T8Server2(serverPort);
for(int i=0; i<3; i++)
mServerThread = new Thread( new Runnable()
@Override
public void run()
boolean flag = true;
String data = null;
while(flag)
if(mServer != null)
mServer.acceptConnectRequest();
data = mServer.getDataFromClient();
if(data != null)
System.out.println("---> Server get data < "+data+" > form Client.");
System.out.println();
if(data.contains("5") || data.contains("3") || data.contains("2"))
flag = false;
else
flag = false;
);
serverThreadGroup.add(mServerThread);
mServerThread = null;
for(int i=0; i<serverThreadGroup.size(); i++)
System.out.println("start ServerThread:"+(i+1));
serverThreadGroup.get(i).start();
for(int i=0; i<5; i++)
String id = String.valueOf(i+1);
id = "Client"+id;
mClient = new T8Client2(serverAddress,serverPort,id);
clientGroup.add(mClient);
mClient = null;
for(int i=0; i<clientGroup.size();i++)
mClient = clientGroup.get(i);
System.out.println("<-- Client["+i+"] send request to Server.");
mClient.startRunning();
mClient = null;
// try
// Thread.sleep(100);
// catch(InterruptedException e)
// e.printStackTrace();
//
try
Thread.sleep(3000);
System.out.println("---> server stop running...");
mServer.disconnectClient();
catch(InterruptedException e)
e.printStackTrace();
在控制台中编译并且运行这三个类,可以得到以下结果:
$ javac T8Client2.java T8Server2.java TCPEx3.java
$ java TCPEx3
start ServerThread:1
start ServerThread:2
start ServerThread:3
<-- Client[0] send request to Server.
<-- Client[1] send request to Server.
<-- Client[2] send request to Server.
<-- Client[3] send request to Server.
<-- Client[4] send request to Server.
Server accept the request of Client
Client connect to Server successfully
Server accept the request of Client
Server accept the request of Client
Client connect to Server successfully
Client connect to Server successfully
Client connect to Server successfully
Client connect to Server successfully
---> Server get data < Client1 > form Client.
---> Server get data < Client3 > form Client.
Server accept the request of Client
---> Server get data < Client2 > form Client.
---> Server get data < Client5 > form Client.
---> server stop running...
另外,大家可以去掉迭代模型中客户端启动的延时,然后运行迭代模型和并发模型这两个程序,这样可以综合对比两种不同模型下服务器的响应时间。如何对比?从程序运行结果中看"Server accept the request of Client"的出现时间,在并发模型中比迭代模型中出现要早一些,还有一点是,接收数据。迭代模型中没有获取到某些客户端发来的数据,而并发模型中可以获取所有客户端的发送的数据。
下面是程序的结果,请大家参考,注意不同机器上可能会有不同的运行结果,但是不影响我们分析问题。毕竟是在同一台电脑运行这两种模型的程序。
$ java TCPEx2 //运行迭代模型所在的程序
<-- Client[0] send request to Server.
<-- Client[1] send request to Server.
<-- Client[2] send request to Server.
<-- Client[3] send request to Server.
<-- Client[4] send request to Server.
Client connect to Server successfully
Client connect to Server successfully
Client connect to Server successfully
Client connect to Server successfully
Server accept the request of Client
Client connect to Server successfully
---> Server get data < Client1 > form Client.
Server accept the request of Client
---> Server get data < Client3 > form Client.
Server accept the request of Client
---> Server get data < Client5 > form Client.
---> server stop running...
$ java TCPEx3 //运行并发模型所在的程序
start ServerThread:1
start ServerThread:2
start ServerThread:3
<-- Client[0] send request to Server.
<-- Client[1] send request to Server.
<-- Client[2] send request to Server.
<-- Client[3] send request to Server.
<-- Client[4] send request to Server.
Client connect to Server successfully
Client connect to Server successfully
Server accept the request of Client
Client connect to Server successfully
Client connect to Server successfully
Server accept the request of Client
Server accept the request of Client
Client connect to Server successfully
---> Server get data < Client1 > form Client.
---> Server get data < Client2 > form Client.
Server accept the request of Client
---> Server get data < Client3 > form Client.
---> Server get data < Client4 > form Client.
Server accept the request of Client
---> Server get data < Client5 > form Client.
---> server stop running...
看官们,关于Android中网络通信之TCP通信模型的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!
以上是关于一起Talk Android吧(第三百二十五回:Android中网络通信之TCP通信模型二)的主要内容,如果未能解决你的问题,请参考以下文章
一起Talk Android吧(第三百一十五回:Android中的ActionBar)
一起Talk Android吧(第三百四十五回:解析JSON对象)
一起Talk Android吧(第三百二十六回:Android中的布局编辑器)
一起Talk Android吧(第三百三十五回: Android中的HTTP请求二)