
com.jianggujin.socket.JSocketClient Maven / Gradle / Ivy
/**
* Copyright 2018 jianggujin (www.jianggujin.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jianggujin.socket;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketException;
import javax.net.SocketFactory;
import com.jianggujin.socket.util.JIOUtils;
/**
* 套接字客户端
*
* @author jianggujin
*
*/
public class JSocketClient implements Closeable {
/** 一行结束标志 */
public static final String NETASCII_EOL = "\r\n";
/** 默认套接字工厂 */
private static final SocketFactory DEFAULT_SOCKET_FACTORY = SocketFactory.getDefault();
/** 已经打开的套接字的超时时间 */
protected int timeout;
/** 用于连接的套接字对象 **/
protected Socket socket;
/** 默认端口 */
protected int defaultPort;
/** 套接字输入流 */
protected InputStream input;
/** 套接字输出流 */
protected OutputStream output;
/** 用于创建套接字的工厂 */
protected SocketFactory socketFactory;
/** 默认套接字连接超时时间,0为无限的 */
private static final int DEFAULT_CONNECT_TIMEOUT = 0;
/** 连接超时时间 */
protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
/** 接受缓冲区大小 */
private int receiveBufferSize = -1;
/** 发送缓冲区大小 */
private int sendBufferSize = -1;
/** 连接时使用的代理 */
private Proxy connProxy;
/** 字符集 */
// private Charset charset = Charset.defaultCharset();
/** 主机名称 */
protected String hostname;
public JSocketClient() {
socket = null;
hostname = null;
input = null;
output = null;
timeout = 0;
defaultPort = 0;
socketFactory = DEFAULT_SOCKET_FACTORY;
}
/**
* 用于对连接的立即设置,当套接字练级成功后会执行本方法
*
* @throws IOException
*/
protected void connectAction() throws IOException {
socket.setSoTimeout(timeout);
input = socket.getInputStream();
output = socket.getOutputStream();
}
/**
* 连接
*
* @param host
* @param port
* @throws SocketException
* @throws IOException
*/
public void connect(InetAddress host, int port) throws SocketException, IOException {
hostname = null;
_connect(host, port, null, -1);
}
/**
* 连接
*
* @param hostname
* @param port
* @throws SocketException
* @throws IOException
*/
public void connect(String hostname, int port) throws SocketException, IOException {
this.hostname = hostname;
_connect(InetAddress.getByName(hostname), port, null, -1);
}
/**
* 连接
*
* @param host
* @param port
* @param localAddr
* @param localPort
* @throws SocketException
* @throws IOException
*/
public void connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
hostname = null;
_connect(host, port, localAddr, localPort);
}
/**
* 连接辅助方法
*
* @param host
* @param port
* @param localAddr
* @param localPort
* @throws SocketException
* @throws IOException
*/
private void _connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
socket = socketFactory.createSocket();
if (receiveBufferSize != -1) {
socket.setReceiveBufferSize(receiveBufferSize);
}
if (sendBufferSize != -1) {
socket.setSendBufferSize(sendBufferSize);
}
if (localAddr != null) {
socket.bind(new InetSocketAddress(localAddr, localPort));
}
socket.connect(new InetSocketAddress(host, port), connectTimeout);
connectAction();
}
/**
* 连接
*
* @param hostname
* @param port
* @param localAddr
* @param localPort
* @throws SocketException
* @throws IOException
*/
public void connect(String hostname, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
this.hostname = hostname;
_connect(InetAddress.getByName(hostname), port, localAddr, localPort);
}
/**
* 连接
*
* @param host
* @throws SocketException
* @throws IOException
*/
public void connect(InetAddress host) throws SocketException, IOException {
hostname = null;
connect(host, defaultPort);
}
/**
* 连接
*
* @param hostname
* @throws SocketException
* @throws IOException
*/
public void connect(String hostname) throws SocketException, IOException {
connect(hostname, defaultPort);
}
/**
* 断开连接
*
* @throws IOException
*/
public void disconnect() throws IOException {
JIOUtils.safeClose(socket);
JIOUtils.safeClose(input);
JIOUtils.safeClose(output);
socket = null;
hostname = null;
input = null;
output = null;
}
/**
* 关闭连接,等价于{@link #disconnect()}
*/
@Override
public void close() throws IOException {
this.disconnect();
}
/**
* 判断是否已连接
*
* @return
*/
public boolean isConnected() {
if (socket == null) {
return false;
}
return socket.isConnected();
}
/**
* 判断连接是否可用
*/
public boolean isAvailable() {
if (isConnected()) {
try {
if (socket.getInetAddress() == null) {
return false;
}
if (socket.getPort() == 0) {
return false;
}
if (socket.getRemoteSocketAddress() == null) {
return false;
}
if (socket.isClosed()) {
return false;
}
/*
* these aren't exact checks (a Socket can be half-open), but since
* we usually require two-way data transfer, we check these here
* too:
*/
if (socket.isInputShutdown()) {
return false;
}
if (socket.isOutputShutdown()) {
return false;
}
/* ignore the result, catch exceptions: */
socket.getInputStream();
socket.getOutputStream();
} catch (IOException ioex) {
return false;
}
return true;
} else {
return false;
}
}
/**
* 设置默认端口
*
* @param port
*/
public void setDefaultPort(int port) {
defaultPort = port;
}
/**
* 获得默认端口
*
* @return
*/
public int getDefaultPort() {
return defaultPort;
}
/**
* 设置默认超时时间
*
* @param timeout
*/
public void setDefaultTimeout(int timeout) {
this.timeout = timeout;
}
/**
* 获得默认超时时间
*
* @return
*/
public int getDefaultTimeout() {
return timeout;
}
/**
* 设置已打开的连接超时时间
*
* @param timeout
* @throws SocketException
*/
public void setSoTimeout(int timeout) throws SocketException {
socket.setSoTimeout(timeout);
}
/**
* 获得已打开的连接超时时间
*
* @return
* @throws SocketException
*/
public int getSoTimeout() throws SocketException {
return socket.getSoTimeout();
}
/**
* 设置套接字发送缓冲大小
*
* @param size
* @throws SocketException
*/
public void setSendBufferSize(int size) throws SocketException {
sendBufferSize = size;
}
/**
* 获得套接字发送缓冲大小
*
* @return
*/
protected int getSendBufferSize() {
return sendBufferSize;
}
/**
* 设置套接字接收缓冲大小
*
* @param size
* @throws SocketException
*/
public void setReceiveBufferSize(int size) throws SocketException {
receiveBufferSize = size;
}
/**
* 获得套接字接收缓冲大小
*
* @return
*/
protected int getReceiveBufferSize() {
return receiveBufferSize;
}
/**
* 启用/禁用 TCP_NODELAY(启用/禁用 Nagle 算法)
*
* @param on
* @throws SocketException
*/
public void setTcpNoDelay(boolean on) throws SocketException {
socket.setTcpNoDelay(on);
}
/**
* 测试是否启用 TCP_NODELAY
*
* @return
* @throws SocketException
*/
public boolean getTcpNoDelay() throws SocketException {
return socket.getTcpNoDelay();
}
/**
* 启用/禁用 SO_KEEPALIVE
*
* @param keepAlive
* @throws SocketException
*/
public void setKeepAlive(boolean keepAlive) throws SocketException {
socket.setKeepAlive(keepAlive);
}
/**
* 测试是否启用 SO_KEEPALIVE
*
* @return
* @throws SocketException
*/
public boolean getKeepAlive() throws SocketException {
return socket.getKeepAlive();
}
/**
* 启用/禁用具有指定逗留时间(以秒为单位)的 SO_LINGER
*
* @param on
* @param val
* @throws SocketException
*/
public void setSoLinger(boolean on, int val) throws SocketException {
socket.setSoLinger(on, val);
}
/**
* 获得SO_LINGER 的设置
*
* @return
* @throws SocketException
*/
public int getSoLinger() throws SocketException {
return socket.getSoLinger();
}
/**
* 获得套接字绑定到的本地端口
*
* @return
*/
public int getLocalPort() {
return socket.getLocalPort();
}
/**
* 获取套接字绑定的本地地址
*
* @return
*/
public InetAddress getLocalAddress() {
return socket.getLocalAddress();
}
/**
* 获得套接字连接到的远程端口
*
* @return
*/
public int getRemotePort() {
return socket.getPort();
}
/**
* 获得套接字连接的地址
*
* @return
*/
public InetAddress getRemoteAddress() {
return socket.getInetAddress();
}
/**
* 设置套接字工厂
*
* @param factory
*/
public void setSocketFactory(SocketFactory factory) {
if (factory == null) {
socketFactory = DEFAULT_SOCKET_FACTORY;
} else {
socketFactory = factory;
}
// 重新设置套接字工厂,需要重置代理对象
connProxy = null;
}
/**
* 设置连接超时时间
*
* @param connectTimeout
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* 获得连接超时时间
*
* @return
*/
public int getConnectTimeout() {
return connectTimeout;
}
/**
* 设置代理对象
*
* @param proxy
*/
public void setProxy(Proxy proxy) {
setSocketFactory(new JDefaultSocketFactory(proxy));
connProxy = proxy;
}
/**
* 获得代理对象
*
* @return
*/
public Proxy getProxy() {
return connProxy;
}
public InputStream getInputStream() {
return input;
}
public OutputStream getOutputStream() {
return output;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy