Naga编程的实例应用

       Naga是一个非常小的NIO类库。提供封装Socket和ServerSocket的几个Java类。

简单的类介绍如下:

 

NIOService :创建NIO流的服务对象

NIOServerSocket :相当于IO中ServerSocket

NIOSocket 相当于IO中Socket

ServerSocketObserverAdapter:服务器端ServerSocket的监听适配器

SocketObserverAdapter:客户端SOcket器端的监听适配器

 

 

服务端代码如下:

package com.easyway.space.sockets.naga;

import naga.*;
import naga.packetreader.RegularPacketReader;
import naga.packetwriter.RegularPacketWriter;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 远程请求服务验证的服务端
 * @author longgangbai
 *
 */
public class NagaServer
{
	NagaServer() {
	}

	public static void main(String... args)
	{
		int port =8090;
		// Create a map with users and passwords.
		//创建一个Map用于存储关于用户的信息的
		final Map<String, String> passwords = new HashMap<String, String>();
		passwords.put("Admin", "password");
		passwords.put("Aaron", "AAAAAAAA");
		passwords.put("Bob", "QWERTY");
		passwords.put("Lisa", "secret");
		try
		{
			//创建一个NIOService服务对象
			NIOService service = new NIOService();
			//创建一个NIOServerSocket服务端对象
			NIOServerSocket socket = service.openServerSocket(port);
			//服务端添加相关的监听器
			socket.listen(new ServerSocketObserverAdapter()
			{
				//当连接成功时执行的代码
				public void newConnection(NIOSocket nioSocket)
				{
					System.out.println("Received connection: " + nioSocket);

					// Set a 1 byte header regular reader.
					nioSocket.setPacketReader(new RegularPacketReader(1, true));

					// Set a 1 byte header regular writer.
					nioSocket.setPacketWriter(new RegularPacketWriter(1, true));

					// Listen on the connection.
					//监听到Socket信息是处理方式
					//备注此处采用的是Socket的观察者适配器
					nioSocket.listen(new SocketObserverAdapter()
					{
						/**
						 * 写数据的到客户端
						 * @param socket
						 * @param packet
						 */
						@SuppressWarnings("unused")
						public void notifyReadPacket(NIOSocket socket, byte[] packet)   
						{     
							socket.write(packet);   
						} 
						/**
						 * 连接发生异常时的处理
						 */
						public void connectionBroken(NIOSocket nioSocket, Exception exception)
						{
						}

                        /**
                         * 连接打开时执行的操作
                         */
						public void connectionOpened(NIOSocket nioSocket)
						{
						}
						/**
						 * 接受数据包的信息
						 */
						public void packetReceived(NIOSocket socket, byte[] packet)
						{
							// We received a packet. Should contain two encoded
							// UTF strings with user and password.
							System.out.println("Login attempt from " + socket);
							try
							{
								// Let us unpack the bytes by converting the bytes to a stream.
								//获取输入的信息
								DataInputStream stream = new DataInputStream(new ByteArrayInputStream(packet));

								// Read the two strings.
								//获取相关的信息
								String user = stream.readUTF();
								String password = stream.readUTF();

								// Prepare to encode the response.
								ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
								DataOutputStream out = new DataOutputStream(byteArrayOutputStream);

								if (!passwords.containsKey(user))
								{
									System.out.println("Unknown user: " + user);
									out.writeUTF("NO_SUCH_USER");
								}
								else if (!passwords.get(user).equals(password))
								{
									out.writeUTF("INCORRECT_PASS");
									System.out.println("Failed login for: " + user);
								}
								else
								{
									out.writeUTF("LOGIN_OK");
									System.out.println("Successful login for: " + user);
								}

								// Create the outgoing packet.
								out.flush();
								//写数据到客户端
								socket.write(byteArrayOutputStream.toByteArray());

								// Close after the packet has finished writing.
								//关闭当前写入流
								socket.closeAfterWrite();
							}
							catch (IOException e)
							{
								// No error handling to speak of.
								//关闭当前的连接
								socket.close();
							}
						}
					});
				}
			});
			
			// Allow all logins.
			//允许所有的不同的ip连接服务器
			socket.setConnectionAcceptor(ConnectionAcceptor.ALLOW);

			// Keep reading IO forever.
			//保持服务为阻塞状态的信息
			while (true)
			{
				service.selectBlocking();
			}
		}
		catch (IOException e)
		{
		}
	}


}

 

 

 

客户端代码如下:

package com.easyway.space.sockets.naga;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;

import naga.NIOService;
import naga.NIOSocket;
import naga.SocketObserver;
import naga.SocketObserverAdapter;
import naga.packetreader.RegularPacketReader;
import naga.packetwriter.RegularPacketWriter;

/**
 * Naga的远程客户端验证 的客户端的代码
 * @author longgangbai
 *
 */
public class NagaClient
{
	NagaClient()
	{}

	/**
	 * Make a login request to the server.
	 *
	 * @param args assumed to be 4 strings representing host, port, account and password.
	 */
	public static void main(String... args)
	{
		try
		{
			// Parse arguments.
			String hostName = "localhost";
			int port = 8090;
			//设置登录的账号信息
			String account ="Admin";
			String password = "password";

			// Prepare the login packet, packing two UTF strings together
			// using a data output stream.
			//将信息写入流中发送到服务端
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			DataOutputStream dataStream = new DataOutputStream(stream);
			dataStream.writeUTF(account);
			dataStream.writeUTF(password);
			dataStream.flush();
			final byte[] content = stream.toByteArray();
			dataStream.close();

			// Start up the service.
			//设置NIOService的服务对象
			NIOService service = new NIOService();

			//获取相关的ip的信息
			InetAddress intaddress=InetAddress.getByName(hostName);
			// Open our socket.
			//打开当前请求的Socket的对象
			NIOSocket socket = service.openSocket(intaddress.getHostAddress(), port);

			// Use regular 1 byte header reader/writer
			//设置读写信息包的信息
			socket.setPacketReader(new RegularPacketReader(1, true));
			socket.setPacketWriter(new RegularPacketWriter(1, true));

			// Start listening to the socket.
			//添加相关的监听事件用于监听客户端
			socket.listen(new SocketObserver()
			{
				/** A null object used as the default observer */
				SocketObserver NULL = new SocketObserverAdapter();
				/**
				 * 连接成功时的相关的操作
				 */
				public void connectionOpened(NIOSocket nioSocket)
				{
					System.out.println("Sending login...");
					nioSocket.write(content);
				}
                //用于接收服务端的信息
				public void packetReceived(NIOSocket socket, byte[] packet)
				{
					try
					{
						// Read the UTF-reply and print it.
						String reply = new DataInputStream(new ByteArrayInputStream(packet)).readUTF();
						System.out.println("Reply was: " + reply);
						// Exit the program.
						System.exit(0);
					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
				}
                //用于接受服务端连接发生异常时的处理方式
				public void connectionBroken(NIOSocket nioSocket, Exception exception)
				{
					System.out.println("Connection failed.");
					// Exit the program.
					System.exit(-1);
				}
			});
			// Read IO until process exits.
			//采用阻塞式读取IO信息,知道进程退出
			while (true)
			{
				service.selectBlocking();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

}

 

 

 

代码如上有不解,希望大家可以沟通,谢谢!

1、利用“naga-2_1-r42.jar”包进行二次开发; 2、调用NIOService类中的打开socket和serverSocket函数进行编程; 3、例如,服务器端: NIOService service1 = new NIOService(); NIOServerSocket serverSocket = service1.openServerSocket(port); // 设置监听事件,包括打开监听后,关闭后这两个: serverSocket.listen(new ServerSocketObserverAdapter() { public void newConnection(NIOSocket nioSocket) { // 可在此处添加处理事件 } public void serverSocketDied(Exception exception) { // 关闭serverSocket处理 } }); // 还需要一个循环事件,执行事件监听,此处可能需要使用到多线程编程 // 设置接收链接方式 serverSocket.setConnectionAcceptor(ConnectionAcceptor.ALLOW); while (true) { // 循环不断监听事件 service1.selectBlocking(1); } 4、又例如,客户端,包括链接上,接收包,关闭链接后三个事件和write()方法: NIOService service2 = new NIOService(); NIOSocket socket = service2.openSocket(InetAddress.getLocalHost(), port); // 设置接收包格式 nioSocket.setPacketReader(new RegularPacketReader(1, true)); nioSocket.setPacketWriter(new RegularPacketWriter(1, true)); nioSocket.listen(new SocketObserverAdapter() { public void connectionBroken(NIOSocket nioSocket, Exception arg1) { // 打开后处理 System.out.println("Client ip:" + nioSocket.getIp() +" port:"+nioSocket.getPort()+ " disconnected."); nioSocket.close(); isConnected = false; } public void connectionOpened(NIOSocket nioSocket) { // 关闭链接后处理 System.out.println("Client ip:" + nioSocket.getIp() +" port:"+nioSocket.getPort()+ " connected."); } public void packetReceived(NIOSocket nioSocket, byte[] packet) { revNum = nioSocket.getBytesRead(); // 包处理 revDataAndParse(packet); }}); // 还需要一个循环监听事件并执行,此处可能需要使用到多线程编程 while (true) { service2.selectBlocking(1); } 5、该项目开发过程基本上是以上3、4点的封装过程,利用接口编程,实现一个客户端基础类(TCPClientBase) 和服务器端基础类(TCPServerBase),其中客户端基础类有两种方式,一种是使用于单独的客户端的单元;另 一种使用与服务器端接收一个链接后的单元; 6、项目类使用: 1) communication.tcp.client.TCPClientBase是基础抽象类,任何外部使用都必须继承该类,并重写一 个“protected abstract void revDataAndParse(byte[] data);”方法,建议外部重写时,设置成protected&private 以防止类外部调用。同样在继承该基础类时,可以在继承类中添加各种需要的引用及必要的方法,实例在 communication.tcp.example.TCPClientUnit体现,重写revDataAndParse方法如下: /** * 处理数据将数据置于队列中,或者直接解析....... */ protected void revDataAndParse(byte[] data) { // SystemOut.arrayToHexString(data); // sendData(data); // System.out.println(new String(data)); } 2) communication.tcp.server.TCPServerBase也是基础抽象类,任何外部使用都必须继承该类,并重写至少包括一些内容: /** * 服务器端构造方法 * @param ip * @param port * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") public TCPServerUnit(String ip, int port) throws ClassNotFoundException { // 注意保持与泛型中的类一致性 super(ip, port,(Class<TCPClientUnit4Server>) Class.forName(TCPClientUnit4Server.class.getName())); } 7、弊端:程序为未经过严格的验证,使用效果如何未知;客户端中的接收包有一定的局限性,接收数据包不利于开发解析,对于实时性要求比较 高的系统不一定适用,如modbusTCP。 8、详细使用过程,请参考doc目录中的api帮助文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值