📄 clientsocket.java
字号:
/* * Copyright (C) butor.com. All rights reserved. * * This software is published under the terms of the GNU Library General * Public License (GNU LGPL), a copy of which has been included with this * distribution in the LICENSE.txt file. */package org.butor.socket.tcp;import java.io.IOException;import java.net.InetSocketAddress;import java.net.Socket;import java.nio.channels.SocketChannel;import org.butor.log.Log;import org.butor.socket.tcp.lowlevel.ReadTimeoutException;import org.butor.socket.tcp.lowlevel.WriteTimeoutException;/** * Extends SocketConnection fonctionnalities. * This class get the host name and port number on which * to create sockets. Socket will be created automaticaly * when needed. * * This class implements retries on read/write operations. * * @see SocketConnection * * @author Aiman Sawan */public class ClientSocket extends SocketConnection { public final static int DEFAULT_MS_WAIT_BEFORE_RETRY = 2000; protected String f_host; protected int f_port; protected int f_maxRetries; protected int f_waitMSBeforeRetry; protected InetSocketAddress f_remote; /** * Constructor. * * @param host String, host name to connect * @param port int, port number to connect */ public ClientSocket(String host, int port) { super(); Log.logStr( Log.LOG_LEVEL_MEDIUM, this, Log.LOG_TYPE_INFO, "Constructor()", ""); f_host = host; f_port = port; f_maxRetries = 0; f_waitMSBeforeRetry = DEFAULT_MS_WAIT_BEFORE_RETRY; } /** * Make a socket connection. */ public boolean connect() { disconnect(); Log.logStr(this, Log.LOG_TYPE_INFO, "connect()", "connecting ..."); try { SocketChannel socketChannel = SocketChannel.open(); Socket socket = socketChannel.socket(); socket.connect(getAddress()); Log.logStr(this, Log.INFO, "connect()", "connected."); if (setSocket(socketChannel)) { fireSocketEvent(SocketEvent.EVENT_CONNECTED, null); return true; } else { fireSocketEvent(SocketEvent.EVENT_CONNECTION_FAILED, null); return false; } } catch (IOException e) { Log.logStr(this, Log.LOG_TYPE_ERROR, "connect()", e.getMessage()); fireSocketEvent(SocketEvent.EVENT_CONNECTION_FAILED, null); return false; } } /** * Set host of the socket * * @param host String, name of the host */ public void setHost(String host) { disconnect(); f_remote = null; f_host = host; } /** * Get host of the socket * * @return String, name of the host */ public String getHost() { return f_host; } /** * Set port number of the socket * * @param port int, number of the port */ public void setPort(int port) { disconnect(); f_remote = null; f_port = port; } /** * Get port number of the socket * * @return int, number of the port */ public int getPort() { return f_port; } /** * write a byte array onto the socket. * * @param buffer byte[], buffer to write * * @return boolean, write success status. */ public boolean write(byte[] buffer) { if (buffer == null) { Log.logStr(this, Log.LOG_TYPE_ERROR, "write(byte[])", "Got NULL buffer to write"); return false; } return this.write(buffer, 0, buffer.length); } /** * write an array of bytes onto the socket. * * @param buffer byte[], buffer to write * @param offset int, starting byte in the array * @param count int, number of bytes to write * * @return boolean, write success status. */ public boolean write(byte[] buffer, int offset, int count) { if (buffer == null) { Log.logStr(this, Log.LOG_TYPE_ERROR, "write(byte[], int, int)", "Got NULL buffer to write"); return false; } int retriesCount = 0; boolean timedOut = false; while (true) { if (!isSane()) { connect(); } if (f_socketIO != null) { try { f_socketIO.write(buffer, offset, count); fireSocketEvent(SocketEvent.EVENT_WRITE_DATA, buffer, offset, count); return true; } catch (WriteTimeoutException e) { timedOut = true; } catch (IOException e) { timedOut = false; Log.logStr(this, Log.LOG_TYPE_ERROR, "write(byte[], int, int)", e.getMessage()); } } if (f_maxRetries == -1) { // retry for ever fireSocketEvent(SocketEvent.EVENT_WRITE_FAILED_RETRY, buffer, offset, count); } else { retriesCount += 1; if (retriesCount > f_maxRetries) { if (timedOut) { fireSocketEvent(SocketEvent.EVENT_WRITE_TIMEOUT, buffer, offset, count); } else { fireSocketEvent(SocketEvent.EVENT_WRITE_FAILED, buffer, offset, count); } return false; } } try { Thread.sleep(f_waitMSBeforeRetry); } catch (InterruptedException e) { } } } /** * read buffer of bytes. * There is two timeouts. one to read a chunk of bytes and the other * to fill the buffer. The first one is used to return after * an elapse of time if there is nothing to read. The other is checked * while filling the buffer. * * @param buffer byte[], buffer to fill * * @return int, number of read bytes. */ public int read(byte[] buffer) { if (buffer == null) { Log.logStr(this, Log.LOG_TYPE_ERROR, "read(byte[])", "Got NULL buffer to read in."); return 0; } return this.read(buffer, 0, buffer.length); } /** * read buffer of bytes. * There is two timeouts. one to read a chunk of bytes and the other * to fill the buffer. The first one is used to return after * an elapse of time if there is nothing to read. The other is checked * while filling the buffer. * * @param buffer byte[], buffer to fill * @param offset int, reading start element in the buffer * @param count int, number of bytes to read. * * @return int, number of read bytes. */ public int read(byte[] buffer, int offset, int count) { int retriesCount = 0; boolean timedOut = false; while (true) { if (!isSane()) { connect(); } int bytesCount = 0; if (f_socketIO != null) { try { bytesCount = f_socketIO.read(buffer, offset, count); fireSocketEvent(SocketEvent.EVENT_READ_DATA, buffer, offset, count); return bytesCount; } catch (ReadTimeoutException e) { timedOut = true; } catch (IOException e) { timedOut = false; Log.logStr(this, Log.LOG_TYPE_ERROR, "read(byte[], int, int)", e.getMessage()); } } if (f_maxRetries == -1) { // retry for ever fireSocketEvent(SocketEvent.EVENT_READ_FAILED_RETRY, null); } else { retriesCount += 1; if (retriesCount > f_maxRetries) { if (timedOut) { fireSocketEvent(SocketEvent.EVENT_READ_TIMEOUT, null); } else { fireSocketEvent(SocketEvent.EVENT_READ_FAILED, null); } return 0; } } try { Thread.sleep(f_waitMSBeforeRetry); } catch (InterruptedException e) { } } } /** * Read until expected bytes are encountered or timeout occure. * will read until the sequence of bytes are encountered. * For example read one line will stop reading and * return a line when the char '\n' will be read. * * @param expectedBytes byte[], Expected sequence of bytes. * * @return byte[], read buffer ending with expected bytes. */ public int readUntilPattern(byte[] buffer, byte[] pattern, int patternSearchOffset) { int retriesCount = 0; boolean timedOut = false; while (true) { if (!isSane()) { connect(); } int bytesCount = 0; if (f_socketIO != null) { try { bytesCount = f_socketIO.readUntilPattern(buffer, pattern, patternSearchOffset); fireSocketEvent(SocketEvent.EVENT_READ_DATA, buffer, 0, bytesCount); return bytesCount; } catch (ReadTimeoutException e) { timedOut = true; } catch (IOException e) { timedOut = false; Log.logStr(this, Log.LOG_TYPE_ERROR, "readUntilPattern(byte[], byte[], int)", e.getMessage()); } } if (f_maxRetries == -1) { // retry for ever fireSocketEvent(SocketEvent.EVENT_READ_FAILED_RETRY, null); } else { retriesCount += 1; if (retriesCount > f_maxRetries) { if (timedOut) { fireSocketEvent(SocketEvent.EVENT_READ_TIMEOUT, null); } else { fireSocketEvent(SocketEvent.EVENT_READ_FAILED, null); } return 0; } } try { Thread.sleep(f_waitMSBeforeRetry); } catch (InterruptedException e) { } } } /** * Get pattern offset. * If last readUntilPattern() contain the pattern * expected then this method will return its starting position. * * @return int. */ public int getPatternEndOffset() { return super.getPatternEndOffset(); } /** * Set number of retries to make a connection. * * @param maxRetries int, amount of retry to do to make a connection. * possible values: * -1 : to try for ever * 0 : no retries to do. Only one attempt to make a connection is done * n : is number of retries to do. */ public void setMaxRetries(int maxRetries) { f_maxRetries = maxRetries; } /** * Get number of retries to make a connection. * * @return int, amount of retry to do to make a connection. */ public int getMaxRetries() { return f_maxRetries; } /** * Set number of milliseconds to wait before retrying to make a connection. * * @param waitMSBeforeRetry int, amount of milliseconds. */ public void setWaitMSBeforeRetry(int waitMSBeforeRetry) { f_waitMSBeforeRetry = waitMSBeforeRetry; } /** * Get number of milliseconds to wait before retrying to make a connection. * * @return int, amount of milliseconds. */ public int getWaitMSBeforeRetry() { return f_waitMSBeforeRetry; } protected InetSocketAddress getAddress() { if (null != f_remote) { return f_remote; } f_remote = new InetSocketAddress(f_host, f_port); return f_remote; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -