package org.cleverframe.fastdfs.conn; import org.cleverframe.fastdfs.constant.CmdConstants; import org.cleverframe.fastdfs.constant.OtherConstants; import org.cleverframe.fastdfs.exception.FastDfsConnectException; import org.cleverframe.fastdfs.utils.BytesUtil; import org.cleverframe.fastdfs.utils.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.Charset; import java.util.Arrays; /** * 默认连接实现 * <p> * 作者:LiZW <br/> * 创建时间:2016/11/20 12:32 <br/> */ public class SocketConnection implements Connection { /** * 日志 */ private static final Logger logger = LoggerFactory.getLogger(SocketConnection.class); /** * 封装socket */ private Socket socket; /** * 字符集 */ private Charset charset; /** * 创建与服务端连接 * * @param address 连接地址 * @param soTimeout soTimeout * @param connectTimeout 设置连接超时 */ public SocketConnection(InetSocketAddress address, int soTimeout, int connectTimeout, Charset charset) { try { socket = new Socket(); socket.setSoTimeout(soTimeout); logger.debug("开始连接到服务器 {} soTimeout={} connectTimeout={}", address, soTimeout, connectTimeout); this.charset = charset; socket.connect(address, connectTimeout); logger.debug("成功连接到服务器:{}", address); } catch (IOException e) { throw new FastDfsConnectException("不能连接到服务器:" + address, e); } } /** * 正常关闭连接 */ public synchronized void close() { logger.debug("断开连接, 服务器地址:{}", socket); byte[] header = new byte[OtherConstants.FDFS_PROTO_PKG_LEN_SIZE + 2]; Arrays.fill(header, (byte) 0); byte[] hex_len = BytesUtil.long2buff(0); System.arraycopy(hex_len, 0, header, 0, hex_len.length); header[OtherConstants.PROTO_HEADER_CMD_INDEX] = CmdConstants.FDFS_PROTO_CMD_QUIT; header[OtherConstants.PROTO_HEADER_STATUS_INDEX] = (byte) 0; try { socket.getOutputStream().write(header); socket.close(); } catch (IOException e) { logger.error("关闭连接失败", e); } finally { IOUtils.closeQuietly(socket); } } /** * 连接是否关闭 */ @Override public boolean isClosed() { return socket.isClosed(); } /** * 检查连接是否有效 */ @Override @SuppressWarnings("SimplifiableIfStatement") public boolean isValid() { logger.debug("检查连接状态 {} ", this.socket); try { byte[] header = new byte[OtherConstants.FDFS_PROTO_PKG_LEN_SIZE + 2]; Arrays.fill(header, (byte) 0); byte[] hex_len = BytesUtil.long2buff(0); System.arraycopy(hex_len, 0, header, 0, hex_len.length); header[OtherConstants.PROTO_HEADER_CMD_INDEX] = CmdConstants.FDFS_PROTO_CMD_ACTIVE_TEST; header[OtherConstants.PROTO_HEADER_STATUS_INDEX] = (byte) 0; socket.getOutputStream().write(header); if (socket.getInputStream().read(header) != header.length) { return false; } return header[OtherConstants.PROTO_HEADER_STATUS_INDEX] == 0; } catch (IOException e) { logger.error("检查连接状态异常", e); return false; } } /** * 获取输出流 */ public OutputStream getOutputStream() throws IOException { return socket.getOutputStream(); } /** * 获取输入流 */ public InputStream getInputStream() throws IOException { return socket.getInputStream(); } /** * 获取字符集 */ public Charset getCharset() { return charset; } }