基于Java自身包实现消息方式的系统间通信的方式有:TCP/IP+BIO,TCP/IP+NIO,UDP/IP+BIO,UDP/IP+NIO.下面就这4种类型一一做个详细的介绍:

一.TCP/IP+BIO

在java中可基于Socket,ServerSocket来实现TCP/IP+BIO的系统间通信。Socket主要用于实现建立连接以及网络IO的操作,ServerSocket主要用于实现服务器端端口的监听及Socket对象的获取。基于Socket实现客户端的代码如下:

public class Client {

    /**
* @param args
*/
public static void main(String[] args) throws Exception{
String host="127.0.0.1";
int port=9527;
Socket socket=new Socket(host,port);
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out=new PrintWriter(socket.getOutputStream(),true);
BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));
boolean flag=true;
while(flag){
String command=systemIn.readLine();
if(command==null || "quit".equalsIgnoreCase(command.trim())){
flag=false;
System.out.println("Client quit!");
out.println("quit");
out.close();
in.close();
socket.close();
continue;
}
out.println(command);
String response=in.readLine();
System.out.println(response);
}
} }

服务器端代码如下:

public class Server {

    /**
* @param args
*/
public static void main(String[] args) throws Exception{
int port=9527;
ServerSocket ss=new ServerSocket(port);
System.out.println("Server listen on port: "+port);
Socket socket=ss.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out=new PrintWriter(socket.getOutputStream(),true);
while(true){
String line=in.readLine();
if(line==null){
Thread.sleep(100);
continue;
}
if("quit".equalsIgnoreCase(line.trim())){
in.close();
out.close();
ss.close();
System.out.println("Server has been shutdown!");
System.exit(0);
}
else{
System.out.println("Message from client: "+ line);
out.println("Server response:"+line);
Thread.sleep(100);
}
}
} }

上面是基于Socket,ServerSocket实现的一个简单的系统间通信的例子。而在实际的系统中,通常要面对的是客户端同时要发送多个请求到服务器端,服务器端则同时要接受多个连接发送的请求,上面的代码显然是无法满足的。

为了满足客户端能同时发送多个请求到服务器端,最简单的方法就是生成多个Socket。但这里会产生两个问题:一是生成太多的Socket会消耗过多的本地资源,在客户端机器多,服务器端机器少的情况下,客户端生成太多Socket会

导致服务器端须要支撑非常高的连接数;二是生成Socket(建立连接)通常是比较慢的,因此频繁的创建会导致系统性能不足。鉴于这两个问题,通常采用连接池的方法来维护Socket是比较好的,一方面限制了能创建的Socket的个数;

另一个方面由于将Socket放入了池中,避免了重复创建Socket带来的性能下降的问题。数据库连接池就是这种方式的典型代表,但连接池的方式会带来另一个问题,连接池中的Socket的个数是有限的,但同时要用socket的请求可能会

很多,在这种情况下就会造成激烈的竞争和等待,还有一个需要注意的问题是合理控制等待响应的超时时间,如不设定会导致当服务器端处理变慢时,客户端相关的请求都在做无限的等待,二客户端的资源必然是有限的。因此这种情况

下很容易造成服务器端出问题时,客户端挂掉的现象。超时时间具体设置为多少取决于客户端能承受的请求量及服务器端的处理时间。既要保证性能,又要保证出错率不会过高,对于直接基于TCP/IP+BIO的方式,可采用Socket.setSotimeout来设置等待响应的超时时间。

二.TCP/IP+NIO

在java中可基于java.nio.channels中的Channel和Selector的相关类来实现TCP/IP+NIO方式的系统间通信。Channel有SocketChannel和ServerSocketChannnel两种,SocketChannel用于建立连接,监听事件及操作读写,

ServerSocketChannel用于监听端口及监听连接事件;程序通过Selector来获取是否有要处理的事件。基于这两个类实现客户端代码如下:

public class Client {

    public static void main(String[] args) throws Exception{
int port=9527;
SocketChannel channel=SocketChannel.open();
channel.configureBlocking(false);
SocketAddress target=new InetSocketAddress("127.0.0.1",port);
channel.connect(target);
Selector selector=Selector.open();
channel.register(selector, SelectionKey.OP_CONNECT);
BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));
while(true){
if(channel.isConnected()){
String command=systemIn.readLine();
channel.write(Charset.forName("UTF-8").encode(command));
if(command==null || "quit".equalsIgnoreCase(command.trim())){
systemIn.close();
channel.close();
selector.close();
System.out.println("Client quit!");
System.exit(0);
}
}
int nKeys=selector.select(1000);
if(nKeys>0){
for (SelectionKey key : selector.selectedKeys()) {
if(key.isConnectable()){
SocketChannel sc=(SocketChannel) key.channel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
sc.finishConnect();
}
else if(key.isReadable()){
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel sc=(SocketChannel) key.channel();
int readBytes=0;
try{
int ret=0;
try{
while((ret=sc.read(buffer))>0){
readBytes+=ret;
}
}
finally{
buffer.flip();
}
if(readBytes>0){
System.out.println(Charset.forName("UTF-8").decode(buffer).toString());
buffer = null;
}
}
finally{
if(buffer!=null){
buffer.clear();
}
}
}
}
selector.selectedKeys().clear();
}
}
} }

服务器端代码如下:

public class Server {

    public static void main(String[] args) throws Exception{
int port=9527;
Selector selector=Selector.open();
ServerSocketChannel ssc=ServerSocketChannel.open();
ServerSocket serverSocket=ssc.socket();
serverSocket.bind(new InetSocketAddress(port));
System.out.println("Server listen on port: "+port);
ssc.configureBlocking(false);
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true){
int nKeys=selector.select(1000);
if(nKeys>0){
for (SelectionKey key : selector.selectedKeys()) {
if(key.isAcceptable()){
ServerSocketChannel server=(ServerSocketChannel) key.channel();
SocketChannel sc=server.accept();
if(sc==null){
continue;
}
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
}
else if(key.isReadable()){
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel sc=(SocketChannel) key.channel();
int readBytes=0;
String message=null;
try{
int ret;
try{
while((ret=sc.read(buffer))>0){
readBytes+=ret;
}
}
catch(Exception e){
readBytes=0;
// IGNORE
}
finally{
buffer.flip();
}
if(readBytes>0){
message=Charset.forName("UTF-8").decode(buffer).toString();
buffer = null;
}
}
finally{
if(buffer!=null){
buffer.clear();
}
}
if(readBytes>0){
System.out.println("Message from client: "+ message);
if("quit".equalsIgnoreCase(message.trim())){
sc.close();
selector.close();
System.out.println("Server has been shutdown!");
System.exit(0);
}
String outMessage="Server response:"+message;
sc.write(Charset.forName("UTF-8").encode(outMessage));
}
}
}
selector.selectedKeys().clear();
}
}
} }

三.UDP/IP+BIO

服务器端代码如下:

public class Server {

    /**
* @param args
*/
public static void main(String[] args) throws Exception{
int port=9527;
int aport=9528;
DatagramSocket server=new DatagramSocket(port);
DatagramSocket client=new DatagramSocket();
InetAddress serverAddress=InetAddress.getByName("localhost");
byte[] buffer=new byte[65507];
DatagramPacket packet=new DatagramPacket(buffer,buffer.length);
while(true){
server.receive(packet);
String line=new String(packet.getData(),0,packet.getLength(),"UTF-8");
if("quit".equalsIgnoreCase(line.trim())){
server.close();
System.exit(0);
}
else{
System.out.println("Message from client: "+ line);
packet.setLength(buffer.length);
String response="Server response"+line;
byte[] datas=response.getBytes("UTF-8");
DatagramPacket responsePacket=new DatagramPacket(datas,datas.length,serverAddress,aport);
client.send(responsePacket);
Thread.sleep(100);
}
}
} }

客户端代码如下:

public class Client {

    /**
* @param args
*/
public static void main(String[] args) throws Exception{
int port=9527;
int aport=9528;
DatagramSocket serverSocket=new DatagramSocket(aport);
byte[] buffer=new byte[65507];
DatagramPacket receivePacket=new DatagramPacket(buffer,buffer.length);
DatagramSocket socket=new DatagramSocket();
InetAddress server=InetAddress.getByName("localhost");
BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));
boolean flag=true;
while(flag){
String command=systemIn.readLine();
byte[] datas=command.getBytes("UTF-8");
DatagramPacket packet=new DatagramPacket(datas,datas.length,server,port);
socket.send(packet);
if(command==null || "quit".equalsIgnoreCase(command.trim())){
flag=false;
System.out.println("Client quit!");
socket.close();
continue;
}
serverSocket.receive(receivePacket);
String receiveResponse=new String(receivePacket.getData(),0,receivePacket.getLength(),"UTF-8");
System.out.println(receiveResponse);
}
} }

四.UDP/IP+NIO

服务器端代码如下:

public class Server {

    public static void main(String[] args) throws Exception{
int rport=9527;
int sport=9528; DatagramChannel sendChannel=DatagramChannel.open();
sendChannel.configureBlocking(false);
SocketAddress target=new InetSocketAddress("127.0.0.1",sport);
sendChannel.connect(target); DatagramChannel receiveChannel=DatagramChannel.open();
DatagramSocket serverSocket=receiveChannel.socket();
serverSocket.bind(new InetSocketAddress(rport));
System.out.println("Data receive listen on port: "+rport);
receiveChannel.configureBlocking(false);
Selector selector=Selector.open();
receiveChannel.register(selector, SelectionKey.OP_READ);
while(true){
int nKeys=selector.select(1000);
if(nKeys>0){
for (SelectionKey key : selector.selectedKeys()) {
if(key.isReadable()){
ByteBuffer buffer=ByteBuffer.allocate(1024);
DatagramChannel dc=(DatagramChannel) key.channel();
dc.receive(buffer);
buffer.flip();
String message=Charset.forName("UTF-8").decode(buffer).toString();
System.out.println("Message from client: "+ message);
if("quit".equalsIgnoreCase(message.trim())){
dc.close();
selector.close();
sendChannel.close();
System.out.println("Server has been shutdown!");
System.exit(0);
}
String outMessage="Server response��"+message;
sendChannel.write(Charset.forName("UTF-8").encode(outMessage));
}
}
selector.selectedKeys().clear();
}
}
} }

客户端代码如下:

public class Client {

    public static void main(String[] args) throws Exception{
int rport=9528;
int sport=9527; DatagramChannel receiveChannel=DatagramChannel.open();
receiveChannel.configureBlocking(false);
DatagramSocket socket=receiveChannel.socket();
socket.bind(new InetSocketAddress(rport));
Selector selector=Selector.open();
receiveChannel.register(selector, SelectionKey.OP_READ); DatagramChannel sendChannel=DatagramChannel.open();
sendChannel.configureBlocking(false);
SocketAddress target=new InetSocketAddress("127.0.0.1",sport);
sendChannel.connect(target); BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in)); while(true){
String command=systemIn.readLine();
sendChannel.write(Charset.forName("UTF-8").encode(command));
if(command==null || "quit".equalsIgnoreCase(command.trim())){
systemIn.close();
sendChannel.close();
selector.close();
System.out.println("Client quit!");
System.exit(0);
}
int nKeys=selector.select(1000);
if(nKeys>0){
for (SelectionKey key : selector.selectedKeys()) {
if(key.isReadable()){
ByteBuffer buffer=ByteBuffer.allocate(1024);
DatagramChannel dc=(DatagramChannel) key.channel();
dc.receive(buffer);
buffer.flip();
System.out.println(Charset.forName("UTF-8").decode(buffer).toString());
buffer = null;
}
}
selector.selectedKeys().clear();
}
}
} }

分布式架构从零开始========》【基于Java自身技术实现消息方式的系统间通信】的更多相关文章

  1. 基于java自身技术实现消息方式的系统间通信

    这篇博客基本照搬了分布式java应用基础与实践一书的内容 java自带的远程调用分两种一种是rmi,一种是webservice 我们先看rmi(remote method invoke)# 使用rmi ...

  2. 基于JAVA WEB技术旅游服务网站系统设计与实现网上程序代写

    基于JAVA WEB技术旅游服务网站系统设计与实现网上程序代写 专业程序代写服务(QQ:928900200) 随着社会的进步.服务行业的服务水平不断发展与提高,宾馆.酒店.旅游等服务行业的信息量和工作 ...

  3. 基于java开发的在线题库系统tamguo

    简介 探果网(简称tamguo)是基于java开发的在线题库系统,包括 在线访问 后台运营 会员中心 书籍中心 管理员账号:system 密码:123456 因为线上数据和测试数据没有做到隔离,作者已 ...

  4. 系统间通信——RPC架构设计

    架构设计:系统间通信(10)——RPC的基本概念 1.概述经过了详细的信息格式.网络IO模型的讲解,并且通过JAVA RMI的讲解进行了预热.从这篇文章开始我们将进入这个系列博文的另一个重点知识体系的 ...

  5. 系统间通信(5)——IO通信模型和JAVA实践 下篇

    7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...

  6. 架构设计:系统间通信(20)——MQ:消息协议(下)

    (接上文<架构设计:系统间通信(19)--MQ:消息协议(上)>) 上篇文章中我们重点讨论了"协议"的重要性.并为各位读者介绍了Stomp协议和XMPP协议. 这两种协 ...

  7. 架构设计:系统间通信(34)——被神化的ESB(上)

    1.概述 从本篇文章开始,我们将花一到两篇的篇幅介绍ESB(企业服务总线)技术的基本概念,为读者们理清多个和ESB技术有关名词.我们还将在其中为读者阐述什么情况下应该使用ESB技术.接下来,为了加深读 ...

  8. 系统间通信(3)——IO通信模型和JAVA实践 上篇

    来源:http://blog.csdn.net/yinwenjie 1.全文提要 系统间通信本来是一个很大的概念,我们首先重通信模型开始讲解.在理解了四种通信模型的工作特点和区别后,对于我们后文介绍搭 ...

  9. Java多线程学习(五)线程间通信知识点补充

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

随机推荐

  1. 用word写博客

    都知道word的编辑功能强大,那如何用word写博客呢? 以博客园为例 1.写好word文档后,文件->共享->发送至博客,或者新建博客模板 2. 再博客的界面点击管理账户,新建账户,如果 ...

  2. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  3. [LeetCode] Copy List with Random Pointe

    题目的关键是要让新链表和原有链表发送关联,可以通过这种关联来设置新链表的random pointer 思路:将新链表的元素插入到原有链表元素的后面,如下图所示,就可以根据原有链表的radom-> ...

  4. [LeetCode] next_permutation

    概念 全排列的生成算法有很多种,有递归遍例,也有循环移位法等等.C++/STL中定义的next_permutation和prev_permutation函数则是非常灵活且高效的一种方法,它被广泛的应用 ...

  5. 用80x86汇编语言编程:1 + 2 + 3 + 4 + 5 + …… + n,和小于100,在屏幕上显示次数和结果。

    ;============================================== ;1+...+n < 100 ;--------------------------------- ...

  6. NoClassDefFoundError:aspectj/weaver/reflect/ReflectionWorld$Reflection

    Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: ...

  7. c++ 的vector

    使用例子:std::vector<std::string> xmlNodeList; 下面介绍-- vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组 ...

  8. 10 steps to becoming the developer everyone wants

    You thought it was all about programming skills. But you were wrong! Great code is fine, yet command ...

  9. 用sql合并列,两句话合为一句

    合并bc两列 UPDATE `test` SET `a`=concat(`b`,`c`) 清空a列 UPDATE `test` SET `a` = NULL

  10. 注意页面上的时间戳可能会成为bd快照的时间_快照不更新的原因

    之前在创建内容的时候,为了提高说服力,添加了一个原始文章的地址**.com.cn/2013-08/22/content_**.htm,当时写文章是在12月份,单快照直接变成原始文章的时间戳8.22