All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.voovan.network.tcp.TcpSocket Maven / Gradle / Ivy
package org.voovan.network.tcp;
import org.voovan.network.*;
import org.voovan.network.exception.ReadMessageException;
import org.voovan.network.exception.SendMessageException;
import org.voovan.network.handler.SynchronousHandler;
import org.voovan.tools.log.Logger;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketOption;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* NioSocket 连接
*
* @author helyho
*
* Voovan Framework.
* WebSite: https://github.com/helyho/Voovan
* Licence: Apache v2 License
*/
public class TcpSocket extends SocketContext {
private SelectorProvider provider;
private SocketChannel socketChannel;
private TcpSession session;
//用来阻塞当前Socket
private Object waitObj = null;
/**
* socket 连接
* 默认不会出发空闲事件, 默认发超时时间: 1s
* @param host 监听地址
* @param port 监听端口
* @param readTimeout 超时时间, 单位: 毫秒
* @throws IOException IO异常
*/
public TcpSocket(String host, int port, int readTimeout) throws IOException{
super(host, port, readTimeout);
init();
}
/**
* socket 连接
* 默认发超时时间: 1s
* @param host 监听地址
* @param port 监听端口
* @param idleInterval 空闲事件触发时间, 单位: 秒
* @param readTimeout 超时时间, 单位: 毫秒
* @throws IOException IO异常
*/
public TcpSocket(String host, int port, int readTimeout, int idleInterval) throws IOException{
super(host, port, readTimeout, idleInterval);
init();
}
/**
* socket 连接
* @param host 监听地址
* @param port 监听端口
* @param idleInterval 空闲事件触发时间, 单位: 秒
* @param readTimeout 超时时间, 单位: 毫秒
* @param sendTimeout 发超时时间, 单位: 毫秒
* @throws IOException IO异常
*/
public TcpSocket(String host, int port, int readTimeout, int sendTimeout, int idleInterval) throws IOException{
super(host, port, readTimeout, sendTimeout, idleInterval);
init();
}
private void init() throws IOException {
this.provider = SelectorProvider.provider();
this.socketChannel = provider.openSocketChannel();
this.socketChannel.socket().setSoTimeout(this.readTimeout);
this.session = new TcpSession(this);
this.connectModel = ConnectModel.CLIENT;
this.connectType = ConnectType.TCP;
}
/**
* 构造函数
* @param parentSocketContext 父 SocketChannel 对象
* @param socketChannel SocketChannel 对象
*/
public TcpSocket(SocketContext parentSocketContext, SocketChannel socketChannel){
try {
this.provider = SelectorProvider.provider();
this.host = socketChannel.socket().getLocalAddress().getHostAddress();
this.port = socketChannel.socket().getLocalPort();
this.socketChannel = socketChannel;
this.socketChannel.configureBlocking(false);
this.copyFrom(parentSocketContext);
this.socketChannel().socket().setSoTimeout(this.readTimeout);
this.connectModel = ConnectModel.SERVER;
this.connectType = ConnectType.TCP;
session = new TcpSession(this);
} catch (IOException e) {
Logger.error("Create socket channel failed",e);
}
}
@Override
public void setIdleInterval(int idleInterval) {
this.idleInterval = idleInterval;
}
/**
* 设置 Socket 的 Option 选项
*
* @param name SocketOption类型的枚举, 参照:SocketChannel.setOption的说明
* @param value SocketOption参数
* @param 范型
* @throws IOException IO异常
*/
@Override
public void setOption(SocketOption name, T value) throws IOException {
socketChannel.setOption(name, value);
}
/**
* 获取 SocketChannel 对象
* @return SocketChannel 对象
*/
@Override
public SocketChannel socketChannel(){
return this.socketChannel;
}
/**
* 获取 Session 对象
* @return Session 对O象
*/
public TcpSession getSession(){
return session;
}
/**
* 启动同步的上下文连接,
* 阻塞方法
* @throws IOException IO 异常
*/
public void start() throws IOException {
syncStart();
waitObj = new Object();
synchronized (waitObj){
try {
waitObj.wait();
} catch (InterruptedException e) {
Logger.error(e);
}
}
}
/**
* 启动同步的上下文连接
* 非阻塞方法
*/
public void syncStart() throws IOException {
initSSL(session);
socketChannel.connect(new InetSocketAddress(this.host, this.port));
socketChannel.configureBlocking(false);
bindToSocketSelector(SelectionKey.OP_READ);
waitConnect();
}
protected void acceptStart() throws IOException {
try {
initSSL(session);
bindToSocketSelector(SelectionKey.OP_READ);
}catch(IOException e){
Logger.error(e);
}
}
@Override
public boolean isOpen() {
if(socketChannel!=null){
return socketChannel.isOpen();
}else{
return false;
}
}
@Override
public boolean isConnected() {
try {
if (socketChannel.isConnected() && socketChannel.getRemoteAddress() != null) {
return true;
} else {
return false;
}
}catch(Exception e){
return false;
}
}
/**
* 同步读取消息
* @return 读取出的对象
* @throws ReadMessageException 读取消息异常
*/
public Object syncRead() throws ReadMessageException {
return session.syncRead();
}
/**
* 同步发送消息
* @param obj 要发送的对象
* @throws SendMessageException 消息发送异常
*/
public void syncSend(Object obj) throws SendMessageException {
session.syncSend(obj);
}
@Override
public boolean close(){
try {
if(socketChannel!=null && socketChannel.isOpen()){
socketChannel.close();
}
return true;
} catch (IOException e) {
Logger.error("TcpSocket.close failed", e);
} finally {
if(session!=null) {
session.release();
}
if(waitObj!=null) {
synchronized (waitObj) {
waitObj.notify();
}
}
}
return false;
}
}