package org.fanhongtao.net.client; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Date; import java.util.Iterator; import org.apache.log4j.Logger; import org.fanhongtao.lang.StringUtils; import org.fanhongtao.log.LogUtils; /** * @author Fan Hongtao * @created 2010-10-21 */ public class Client { private static Logger log = Logger.getLogger(Client.class.getName()); public static final int MAX_LENGTH = 64 * 1024; private ByteBuffer readBuffer = ByteBuffer.allocate(MAX_LENGTH); private ByteBuffer writeBuffer = ByteBuffer.allocate(MAX_LENGTH); private SocketChannel channel; private Selector selector; private String server; private int port; private int msgInterval; private int exitInterval; public Client(String server, int port, int msgInterval, int exitInterval) { this.server = server; this.port = port; this.msgInterval = msgInterval; this.exitInterval = exitInterval; } public void connect() throws IOException { log.info("Try to connect to " + server + " : " + port); InetSocketAddress addr = new InetSocketAddress(server, port); channel = SocketChannel.open(addr); channel.configureBlocking(false); selector = Selector.open(); channel.register(selector, SelectionKey.OP_READ); log.info("Connect successfully. Local port: " + channel.socket().getLocalPort()); } public void disconnect() throws IOException { log.info("disconnect to " + server + " : " + port); channel.close(); } public void sendMessage(String msgFile) throws IOException { log.info("Process file [" + msgFile + "]"); BufferedReader fin = new BufferedReader(new FileReader(msgFile)); // send message(s) to server while (true) { if (selector.select(msgInterval) != 0) { processIOEvent(selector); } byte[] msg = getOneMsg(fin); if (msg.length == 0) { break; } log.debug("Send to server: \n" + StringUtils.toHexString(msg)); writeBuffer.put(msg); writeBuffer.flip(); while (writeBuffer.remaining() != 0) { channel.write(writeBuffer); } writeBuffer.clear(); } // wait last response long currentTime; long exitTime = System.currentTimeMillis() + exitInterval; while ((currentTime = System.currentTimeMillis()) < exitTime) { if (selector.select(exitTime - currentTime) != 0) { processIOEvent(selector); } } log.info("Process file [" + msgFile + "] finished."); } private void processIOEvent(Selector selector) throws IOException { Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); if (key.isReadable()) { receiveFromServer(); } iter.remove(); } } private void receiveFromServer() throws IOException { int count = channel.read(readBuffer); readBuffer.flip(); byte[] temp = new byte[readBuffer.limit()]; readBuffer.get(temp); log.debug("read " + count + " bytes from server, content\n" + StringUtils.toHexString(temp)); readBuffer.clear(); } @SuppressWarnings("deprecation") protected void log(String logInfo) { Date date = new Date(); System.out.println(date.toLocaleString() + ", " + logInfo); } private byte[] getOneMsg(BufferedReader fin) throws IOException { // read a message from file StringBuffer buffer = new StringBuffer(); String line; while ((line = fin.readLine()) != null) { line.trim(); if (line.startsWith("#MsgEnd")) { break; } if (line.startsWith("#")) { log.info(line.substring(1).trim()); continue; } if (line.length() == 0) { continue; } buffer.append(line).append(' '); } // translate message into bytes String[] hexs = buffer.toString().split("[ \t]+"); byte[] data = new byte[hexs.length]; for (int i = 0; i < hexs.length; i++) { data[i] = (byte)Integer.parseInt(hexs[i], 16); } return data; } public static void main(String[] args) { if (args.length < 3) { System.out.println("Usage: Client ip port msgFile [msgInterval] [exitInterval]"); return; } LogUtils.initBasicLog(); String ip = args[0]; int port = Integer.parseInt(args[1]); String msgFile = args[2]; int msgInterval = (args.length > 3) ? Integer.parseInt(args[3]) : 1000; int exitInterval = (args.length > 4) ? Integer.parseInt(args[4]) : 10000; Client client = new Client(ip, port, msgInterval, exitInterval); try { client.connect(); client.sendMessage(msgFile); client.disconnect(); } catch (IOException e) { log.error("Failed to process", e); } } }