- 浏览: 242178 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
maotou1988:
android基于netty的发送图片与文字demo,楼主共勉 ...
在android中使用netty框架通信 -
ZSRTFAT:
学习了,谢谢分享
android 基于surfaceview 的多点触控实现 -
charlotte:
学习了!!!!!
Java nio 客户端连接Server -
nilo:
您好, 本人菜鸟, 正在学习设计模式. 当我学习完简单工厂模式 ...
策略模式 -
fokman:
<div class="quote_title ...
Java nio 客户端连接Server
在做通信系统的开发过程中,经常需要使用Socket通信。java新的io机制给我提供了一个很好的异步socket通信方式,这段时间用java写了一个客户端用来连接server。发现运行效率还比较让人满意。下面是我实现的部分功能。
连接服务器的socket,多线程启动。如果连接失败就重连。
public class CommonSocket extends Thread { private SocketChannel socketChannel; private boolean stop = false; private int port = 0; private String ip = ""; private Selector selector = null; private SocketAddress socketAddress = null; private Logger logger = Logger.getLogger(CommonSocket.class); public CommonSocket() { this.ip = SocketInfoUtils.TCP_IP; this.port = SocketInfoUtils.TCP_PORT; } public void run() { while (!stop) { socketConnet(); try { sleep(5000); } catch (InterruptedException e) { logger.error("SocketConnect run error: InterruptedException"); } } } public void socketBuilder() { try { selector = Selector.open(); } catch (IOException e) { e.printStackTrace(); logger.error("Open to selector failed: IOException"); } } private void openSocketChannel() { try { socketAddress = new InetSocketAddress(ip, port); socketChannel = SocketChannel.open(); socketChannel.socket().setReuseAddress(true); socketChannel.connect(socketAddress); } catch (ClosedChannelException e) { logger.warn("Channel is closed: ClosedChannelException"); } catch (IOException e) { logger .warn("Connet is failed or time out,the system will automatically re-connected : IOException"); } } /** * do ClientBuilder if socket conncte success */ public void socketConnet() { try { openSocketChannel(); if (socketChannel.isOpen()) { this.stop = true; socketBuilder(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); PackageBuilder clientBuilder = new PackageBuilder(socketChannel, selector); clientBuilder.start(); logger.info("Has been successfully connected to " + ip + "and port: " + port); } else { socketChannel.close(); } } catch (ClosedChannelException e) { logger.warn("Channel is closed: ClosedChannelException"); } catch (IOException e) { logger .warn("Connet is failed or time out,the system will automatically re-connected : IOException"); } } }
发送和接收事件处理,NIO是基于事件的驱动模型,这个类就是专门处理收发的。
public class PackageBuilder extends Thread{ private SocketChannel socketChannel = null; private Selector selector = null; private boolean stop = false; private byte[] array = new byte[1024]; private ByteBuffer byteBuffer; private PackageQueue packageQueue; private Logger logger = Logger.getLogger(PackageBuilder.class); public PackageBuilder(SocketChannel socketChannel,Selector selectore){ this.socketChannel = socketChannel; this.selector = selectore; packageQueue=new PackageQueue(); } public void run(){ try { while (!stop) { Thread.sleep(1); if(!socketChannel.isOpen()){ reconnect();//通道没打开或者断开执行重连工作(Channel did not open the work of the implementation of re-connection ) break; } if (selector.select(30) > 0) { doSelector(); } } } catch (IOException e) { logger.error("CameraBuilder run error: IOException"); } catch (InterruptedException e){ logger.error("CameraBuilder run error: InterruptedException"); } } public void doSelector(){ for(SelectionKey key:selector.selectedKeys()){ selector.selectedKeys().remove(key); if(!key.isValid()){ continue; } doKeys(key); } } public void doKeys(SelectionKey key){ SocketChannel channel = (SocketChannel)key.channel(); if(key.isReadable()){ readResponse(channel); } if(key.isWritable()){ sendRequest(channel); } } private void readResponse(SocketChannel channel) { byteBuffer=ByteBuffer.wrap(array); byteBuffer.clear(); int count = 0; try { count = channel.read(byteBuffer); } catch (IOException e) { reconnect();//通道没打开或者断开执行重连工作(Channel did not open the work of the implementation of re-connection ) logger.error("Connection reset by peer: IOException"); } if(count != -1){ byteBuffer.flip(); byte[] bs = new byte[count]; byteBuffer.get(bs); ByteBuffer returnBuffer = ByteBuffer.allocate(count); returnBuffer.clear(); returnBuffer.put(bs); returnBuffer.flip(); PrintUtil.printBf(returnBuffer.array()); ParseBufferData parseData=new ParseBufferData(returnBuffer); parseData.parseBuffer(); } if(count < 0){ reconnect(); } } /** * send pakcet of request * @param channel */ public void sendRequest(SocketChannel channel){ byte[] array = packageQueue.takeMsgs(); if(array!=null){ ByteBuffer byteBuffer = ByteBuffer.wrap(array); try { channel.write(byteBuffer); } catch (IOException e) { reconnect();//通道没打开或者断开执行重连工作(Channel did not open the work of the implementation of re-connection ) logger.warn("socket not connected or has been closed: IOException"); } } } public void reconnect(){ stopClient(); logger.warn("socket not connected or has been closed"); ThreadPoolUtil.getExecutor().execute(new CameraSocket()); } public void stopClient(){ this.stop = true; if(socketChannel.isConnected() && !socketChannel.isOpen()){ try { socketChannel.close(); logger.info("server_socket has connected"); } catch (IOException e) { logger.warn("Channel closed to failed: IOException"); } } } }
发送和接收数据存放在缓存中
public class PackageQueue { private static List<byte[]> queue = new ArrayList<byte[]>(); public PackageQueue(){ } public void pushMsgs(byte[] array){ synchronized(queue){ queue.add(array); } } public byte[] takeMsgs() { synchronized (queue) { byte[] sd=null; if(queue != null){ if(queue.size() > 0){ sd = queue.get(0); queue.remove(0); } } return sd; } } public static List<byte[]> getQueue() { return queue; } public static void setQueue(List<byte[]> queue) { PackageQueue.queue = queue; } }
以上就是客户端连接、发送、接收的代码。希望对大家有所帮助
评论
3 楼
charlotte
2012-05-14
学习了!!!!!
2 楼
fokman
2011-08-17
一江春水邀明月 写道
缺少SocketInfoUtils ThreadPoolUtil CameraSocket 三个类的代码啊, 博主能把这三个类也贴一下吗? 谢谢了
public class CameraSocket extends Thread {
private int cmdPort = SocketInfoUtils.CMD_PORT; // 5554
private String host = SocketInfoUtils.HOST; // 172.16.163.38
ByteBuffer buffer = ByteBuffer.allocate(1024);
// DatagramChannel dataChannel;
DatagramChannel cmdChannel;
Selector selector;
CameraQueue cameraQueue;
public CameraSocket() throws Exception {
selector = Selector.open();
cameraQueue = new CameraQueue();
cmdChannel = DatagramChannel.open();
cmdChannel.configureBlocking(false);
SocketAddress target = new InetSocketAddress(host, cmdPort);
cmdChannel.connect(target);
cmdChannel.register(selector, SelectionKey.OP_WRITE);
}
@Override
public void run() {
boolean flag = true;
while (flag) {
try {
doSelector();
} catch (IOException e) {
flag = false;
e.printStackTrace();
}
}
}
private void doSelector() throws IOException {
if (selector.select(1000) > 0) {
for (SelectionKey key : selector.selectedKeys()) {
if (key.isWritable()) {
writeEvent(cmdChannel);
}
}
selector.selectedKeys().clear();
}
}
// private void readEvent(SelectionKey key) throws IOException {
// ByteBuffer buffer = ByteBuffer.allocate(1024);
// dataChannel.receive(buffer);
// buffer.flip();
// ParseBufferData parseBufferData=new ParseBufferData(buffer);
// parseBufferData.parseBuffer();
// }
private void writeEvent(DatagramChannel channel) throws IOException {
byte[] array = cameraQueue.takeMsgs();
if (array != null) {
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
try {
channel.write(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class SocketInfoUtils {
public static Properties factory = SocketPropertiesFactory.getInstance().getBoundle();
public static String TCP_IP = factory.getProperty("tcp_ip");
public static int TCP_PORT = Integer.parseInt(factory.getProperty("tcp_port"));
public static int CAMERA_PORT=Integer.parseInt(factory.getProperty("camera_port"));
//public static int UDP_PORT = Integer.parseInt(factory.getProperty("udp_port"));
public static int HIS_UDP_PORT = Integer.parseInt(factory.getProperty("his_udp_port"));
public static int CMD_PORT = Integer.parseInt(factory.getProperty("cmd_port"));
public static int DATA_PORT = Integer.parseInt(factory.getProperty("data_port"));
public static final String HOST = factory.getProperty("host");
}
public class ThreadPoolUtil {
private static ThreadPoolExecutor executor;
static{
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(1);
executor = new ThreadPoolExecutor(5,100,500,TimeUnit.MILLISECONDS,queue);
RejectedExecutionHandler rejected = new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println(String.format("======= Task %d rejected.======", r.hashCode()));
}
};
executor.setRejectedExecutionHandler(rejected);
}
public static ThreadPoolExecutor getExecutor() {
return executor;
}
public static void setExecutor(ThreadPoolExecutor executor) {
ThreadPoolUtil.executor = executor;
}
}
1 楼
一江春水邀明月
2011-06-30
缺少SocketInfoUtils ThreadPoolUtil CameraSocket 三个类的代码啊, 博主能把这三个类也贴一下吗? 谢谢了
发表评论
-
Centos7 配置JDK 提示 /lib/ld-linux.so.2: bad ELF interpreter: No such file or direct
2018-06-26 14:26 1573今天重新搭配一套环境,在CentOs7上面重新安装了jdk1 ... -
ubuntu 16.04下安装JDK8
2018-04-20 17:10 562下载JDK8 http://www.oracle.com/ ... -
团队开发统一eclipse格式
2012-09-04 10:37 1061在团队协作开发的时候,通常各人的编码风格不同,导致写出 ... -
java枚举存入map
2012-06-27 12:05 12725在jdk1.5中java引入了枚举类型,今天我们就将枚举 ... -
工厂方法模式
2012-06-16 11:21 930简单工厂模式和工厂方法模式的区别在哪里呢? 简单 ... -
在android中使用netty框架通信
2012-02-08 10:48 42159最近在做一个项目,基于android版本的一个物联网应 ... -
使用bouncycastle进行加密
2011-11-25 09:46 32294BouncyCastle是一个开源的加解密解决方案,主页在ht ... -
用一个for循环实现99乘法表
2011-08-18 09:00 3767前两天去武汉融众科技去面试,有一道笔试题是用一个for循环实现 ... -
Java nio Server实现
2011-06-11 16:48 3669Java NIO 提供了反应堆模式非阻塞的Socket通信,代 ... -
Java nio Server实现
2011-06-11 16:22 1一个java简单的NIO Server 实现 public ... -
在java switch中使用String作为分支条件
2011-06-02 11:32 2648在java中明确规定switch里面只允许使用int,char ... -
代理模式
2011-05-31 22:38 952在我们的日常生活中通常需要通过第三方的介绍来办理相关 ... -
装饰模式
2011-05-30 21:20 1146装饰模式就像我们穿衣服一样,先穿什么、然后在穿什么。它的意思就 ... -
策略模式
2011-05-29 22:36 1255策略模式:定义了算法家族,分别封装起来,让他们时间可以相互替换 ... -
简单工厂模式
2011-05-28 14:00 1030面向对象的程序设计就是通过封装、继承、多态把程序的耦合度降低。 ... -
Java 通信中常用到的数据转码
2011-03-14 09:42 2090在写java通信的时候,经常需要进行数据的解包和组包工作,我们 ...
相关推荐
该JAVA NIO项目包含server服务端完整项目源码、client客户端项目工程源码。
在这个场景下,Java NIO能够帮助服务器有效地处理多个客户端连接,并实现客户端之间消息的互发。 首先,我们要理解Java NIO的基本组件。主要包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是...
在这个Java NIO IM(即时通讯)服务器和客户端的示例中,我们将探讨如何利用NIO进行双向通信,并理解其背后的机制。 1. **NIO基础概念** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的。通道类似于流...
在`NIOServer.java`中,可能会创建ServerSocketChannel监听客户端连接,然后通过accept()方法接收新连接,形成SocketChannel。 6. **Pipe**:在本地进程间通信(IPC)中使用,提供单向数据流。 7. **CharSet和...
首先,我们来看`NioServer.java`。这个文件中包含了一个基于NIO的服务器端实现。服务器的核心组件是`Selector`,它允许一个单独的线程监听多个套接字通道的状态变化。当客户端发起连接请求时,服务器会注册`...
而"TestNIO_client"和"TestNIO_server"这两个文件名很可能分别对应的是NIO客户端和服务器的源代码文件,用户可以通过这些源代码了解如何在J2ME和Java NIO之间建立有效的通信。 在实际应用中,J2ME客户端可能使用...
为了更好地理解Java NIO的使用方式,下面我们通过简单的代码示例来展示如何实现一个基本的NIO服务端和客户端。 **服务端代码实现** ```java package cn.nio; import java.io.IOException; import java.net....
以下是一个简单的Java NIO客户端示例,名为DownloadClient.java: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey;...
Java NIO(New IO)是Java 1.4版本引入的一种新的I/O API,它提供了非阻塞I/O操作的能力,极大地提升了Java在处理网络通信和文件读写时的性能。在这个“java nio聊天室源码”项目中,我们可以看到如何使用NIO构建一...
在Java中,我们可以使用`java.net.Socket`类来创建客户端连接,它代表了两台机器之间的网络连接。Socket编程是基于TCP/IP协议的,确保了数据的可靠传输。要实现FTP客户端,首先需要创建一个Socket连接到FTP服务器,...
1. **服务器端**:服务器端使用NIO的ServerSocketChannel监听客户端连接。当新的客户端连接请求到达时,服务器会创建一个新的SocketChannel来处理这个连接,而不是像阻塞IO那样阻塞等待。这样服务器就可以继续监听...
- **Java NIO**:能够有效地利用系统资源,支持更多的并发连接,因此在处理大量连接请求时性能更优。 #### 应用场景 - **Java IO**:适用于数据量较小且连接数较少的应用场景。 - **Java NIO**:适用于数据量大、...
在NIO中,服务器端通常使用Selector来监听多个客户端连接。当新的连接请求到达时,服务器会创建一个SocketChannel,并将其注册到Selector上,指定感兴趣的操作类型(如Accept、Read)。Selector会轮询所有注册的通道...
**NIO客户端(TestClient.java)的关键知识点:** 1. **套接字通道(SocketChannel)**:客户端通过`SocketChannel.open()`创建通道,并用`socketChannel.connect(new InetSocketAddress(serverAddress, serverPort...
本例包含服务器端和客户端,多线程,每线程多次发送,Eclipse工程,启动服务器使用 nu.javafaq.server.NioServer,启动客户端使用 nu.javafaq.client.NioClient。另本例取自javafaq.nv上的程序修改而成
使用NIO socket不需要多线程来处理多个连接的请求,效率非常高 ...4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合java2D和robot做远程监控 5,封装自己的协议可以做成自己需要的服务器端程序,
例如,可能有一个名为`NioServer`的主类,用于初始化ServerSocketChannel,注册选择器,以及处理接收到的连接和数据。还有可能包含`ThreadPool`类,用于管理线程池,以及`BufferHandler`类,负责处理缓冲区中的数据...
【文件】:“NIOServer.java”是整个项目的主文件,很可能包含了服务器的启动逻辑、NIO服务的配置以及客户端连接的处理。代码可能包括以下几个关键部分: 1. **服务器端套接字(ServerSocketChannel)**:服务器...
Java NIO(New IO)是Java 1.4版本引入的一个新特性,它提供了一种不同于传统IO(-blocking I/O)的I/O操作方式。传统的IO模型是基于流的,通常涉及阻塞式读写,而NIO则引入了通道(Channels)和缓冲区(Buffers)的...
这个例子包含了NIO在网络通信中的应用,包括服务器端(Server)和客户端(Client)的实现。 在Java NIO中,核心组件有通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是数据传输的途径,如套接字...