通过导出的jar包无法运行Socket通信程序时,服务器端会无故终止

天弈isai 2015-05-07 09:55:43
用SocketChannel写了一个服务器跟客户端进行Socket通信的工具,通过MyEclipse启动时,程序能够正常允许,客户端和服务气端的通信也能够顺利进行交互。
但是,导出jar包后,用jar包直接启动后,在客户端连接到服务器端,服务器端接收到客户端的信息,进行解析时(在一个新线程中解析数据),服务器端的Socket突然跳出循环,终止掉了。
通过输出的日志,可以确认,服务器端终止前没有异常发生,也没有进入终止循环的处理。
调查了很久,还没有找到原因,哪位朋友知道可能原因或方向,请不吝指导,谢谢。

注:通过MyEclipse运行时,完全正常,只是通过导出的jar文件运行是有问题。

以下是服务器端代码:

public class TCPServer extends BasicThread {
public static final int vRecieveDataSize = 4096; // 庴怣僨乕僞偺僒僀僘丅

private boolean mServerAlive = false;
private int mPortNumer;
private int mRecieveDataSize = vRecieveDataSize;
Selector mSelector;
ServerSocketChannel mServerSocketChannel;

/**
* 僐儞僗僩儔僋僞丅<BR>
*
* @param portNumber 億乕僩斣崋
*/
public TCPServer(int portNumber) {
mServerAlive = true;
mPortNumer = portNumber;
}

/**
* 僐儞僗僩儔僋僞丅<BR>
*
* @param portNumber 億乕僩斣崋
* @param bufferSize 庴怣僨乕僞僒僀僘
*/
public TCPServer(int portNumber, int bufferSize) {
mServerAlive = true;
mPortNumer = portNumber;
mRecieveDataSize = bufferSize;
}

/**
* 愙懕/愗抐/庴怣晹丅<BR>
*/
public void run() {
mSelector = null;
mServerSocketChannel = null;

try {
mSelector = Selector.open();
mServerSocketChannel = ServerSocketChannel.open();
mServerSocketChannel.configureBlocking(false);
mServerSocketChannel.socket().bind(new InetSocketAddress(mPortNumer));
mServerSocketChannel.register(mSelector, SelectionKey.OP_ACCEPT);

LoggerUtil.putLog("Open: Port=" + mPortNumer);

while (mIsActive && mServerAlive) {
mSelector.select();
Iterator<SelectionKey> iterator = mSelector.selectedKeys().iterator();
LoggerUtil.putLog("iterator.hasNext() = " + iterator.hasNext());

try {
while (iterator.hasNext() && mIsActive && mServerAlive) {
SelectionKey selectionKey = (SelectionKey)iterator.next();
iterator.remove();
// 愙懕帪丅
if (selectionKey.isAcceptable()) {
SocketChannel socketChannel = (SocketChannel)mServerSocketChannel.accept();
if (socketChannel == null) {
LoggerUtil.putLog("socketChannel is null");
continue;
}
LoggerUtil.putLog("Socket accept: port=" + mPortNumer + " IP=" + socketChannel.socket().getInetAddress().getHostAddress());
socketChannel.configureBlocking(false);
socketChannel.register(mSelector, SelectionKey.OP_READ);
// 愙懕偝傟偨僋儔僀傾儞僩傪捠抦偡傞丅
ClientSocketConnect(socketChannel);
}
// 撉崬帪丅
if (selectionKey.isReadable()) {
SocketChannel socketChannel = (SocketChannel)selectionKey.channel();

try {
ByteBuffer byteBuffer = ByteBuffer.allocate(mRecieveDataSize);
int size = socketChannel.read(byteBuffer);
if (size == -1) {
LoggerUtil.putLog("Socket receive: port=" + mPortNumer + " IP=" + socketChannel.socket().getInetAddress().getHostAddress() + " data=-1");
// 愗抐偝傟偨僋儔僀傾儞僩傪捠抦偡傞丅
ClientSocketClose(socketChannel);
break;
}

// 僨僶僢僌梡丅
byteBuffer.flip();
byte[] buffer = new byte[byteBuffer.limit()];
byteBuffer.get(buffer);
String data = new String (buffer);

LoggerUtil.putLog("Socket receive: port=" + mPortNumer + " IP=" + socketChannel.socket().getInetAddress().getHostAddress() + System.getProperty("line.separator") + "data=" + data);

socketChannel.socket().setTcpNoDelay(true);
socketChannel.socket().setKeepAlive(true);
socketChannel.socket().setSoLinger(true, 0);

// 庴怣偟偨撪梕傪捠抦偡傞丅
this.GetBuffer(socketChannel, byteBuffer);
} catch (IOException e) {
LoggerUtil.putErrorLog("IOException : " + e.getMessage());
// 儂僗僩偺嫮惂愗抐摍椺奜丅
ClientSocketClose(socketChannel);
}
}
}
} catch (CancelledKeyException e) {
// 儂僗僩偵懳偟偰愗抐張棟傪峴偄丄僉乕憖嶌偑柍岠偲側偭偨丅
LoggerUtil.putErrorLog("CancelledKeyException : " + e.getMessage());
} catch (SecurityException e) {
LoggerUtil.putErrorLog("SecurityException : " + e.getMessage());
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
}
}
} catch (ClosedSelectorException e) {
// CoffeeThread廔椆屻偺mSelector.select()偺懸婡夝彍帪丅
LoggerUtil.putLog("ClosedSelectorException");
} catch (IOException e) {
LoggerUtil.putErrorLog("IOException NG: " + e.getMessage());
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
} finally {
LoggerUtil.putLog("mServerAlive = " + mServerAlive + " mIsActive = " + mIsActive);
if (mServerAlive) {
// 愗抐張棟偑峴傢傟偰偄側偄応崌丅
SocketChannelClose();
}
}
LoggerUtil.putLog("ServerSocket End");
}

/**
* 庴怣僨乕僞偺捠抦丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
* @param byteBuffer 庴怣僨乕僞
*/
protected void GetBuffer(SocketChannel socketChannel, ByteBuffer byteBuffer) {
}

/**
* 僋儔僀傾儞僩偺愙懕忬懺妋擣丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
* @return 愙懕忬懺
*/
public static boolean IsConnected(SocketChannel socketChannel) {
boolean connected = false;

try {
if (socketChannel != null) {
connected = socketChannel.isConnected();
if (! connected) {
LoggerUtil.putLog("socketChannel is not connected");
}
} else {
LoggerUtil.putLog("socketChannel is null");
}
// TCP僒乕僶偲TCP僋儔僀傾儞僩偺椺奜張棟傪嫮壔丅
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
}

return connected;
}

/**
* 僋儔僀傾儞僩偺愙懕捠抦丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
*/
protected void ClientSocketConnect(SocketChannel socketChannel) {
}

/**
* 僋儔僀傾儞僩偺愗抐捠抦丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
*/
private void ClientSocketClose(SocketChannel socketChannel) {

try {
SocketClose(socketChannel);
socketChannel.close();
} catch (IOException e) {
LoggerUtil.putErrorLog("IOException NG : " + e.getMessage());
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
}
}

/**
* 僜働僢僩偺愗抐傪捠抦偡傞丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
*/
protected void SocketClose(SocketChannel socketChannel) {
}

/**
* 僜働僢僩偺愗抐傪捠抦偡傞丅<BR>
*
* @param isActive 廔椆張棟敾掕
*/
protected void SocketClose(boolean isActive) {
}

/**
* 僜働僢僩傪愗抐偡傞丅<BR>
*
* @param socketChannel 僜働僢僩忣曬
*/
public static void SocketChannelClose(SocketChannel socketChannel) {
try {
if (socketChannel != null && socketChannel.isConnected()) {
socketChannel.socket().shutdownOutput();
}
} catch (IOException e) {
LoggerUtil.putErrorLog("IOException NG : " + e.getMessage());
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
}
}

/**
* 僜働僢僩僠儍儞僱儖傪廔椆偡傞丅<BR>
*/
protected void SocketChannelClose() {
mServerAlive = false;
try {
Iterator<SelectionKey> itr = mSelector.keys().iterator();
while (itr.hasNext()) {
SelectionKey key = (SelectionKey)itr.next();
Channel channel = key.channel();
LoggerUtil.putLog("ServerSocket Close: " + channel.toString());
channel.close();
}
SocketClose(mIsActive);
mSelector.close();
mServerSocketChannel.close();
} catch (IOException e) {
LoggerUtil.putErrorLog("IOException NG : " + e.getMessage());
} catch (Exception e) {
LoggerUtil.putErrorLog("Exception NG: " + e.getMessage());
}
}
}


以下是输出的log:

2015/05/06 21:07:27.271, INFO , TCPServer.run(70) Open: Port=58002 ==> 服务器端启动
2015/05/06 21:07:27.287, INFO , TCPServer.run(75) iterator.hasNext() = true
2015/05/06 21:07:27.287, INFO , TCPServer.run(88) Socket accept: port=58002 IP=127.0.0.1 ==> 客户端连接到服务器端
2015/05/06 21:07:29.159, INFO , HostSystemSocketClient.Connect(267) ClientSocket Connect : IpAddress=127.0.0.1 PortNumber=58002
2015/05/06 21:07:29.190, INFO , TCPServer.run(75) iterator.hasNext() = true
2015/05/06 21:07:29.190, INFO , TCPServer.run(114) Socket receive: port=58002 IP=127.0.0.1 ==> 接收到客户端发送的信息
data=000225<?xml version="1.0" encoding="UTF-8"?>
<root>
<Header>
<SystemName>OTHERSYSTEM</SystemName>
<SystemVersion>1.00</SystemVersion>
<SessionId>1</SessionId>
<CommandName>Connect</CommandName>
</Header>
</root>

2015/05/06 21:07:29.190, SEVERE , LnbTransactionManager.GetHostTransactionByHostName(36) Transaction Get NG: HostName=127.0.0.1
2015/05/06 21:07:29.190, INFO , LnbTransactionManager.CreateTransaction(52) Transaction Create OK: hostName=127.0.0.1
2015/05/06 21:07:29.206, INFO , LnbSocket.run(119) ComponentVerificationSocket thread start ==> 创建并启动一个新的进程来解析接收到的客户端数据
2015/05/06 21:07:29.206, SEVERE , LnbSocket.ChecktReceiveData(349) 开始解析数据 ==> 开始解析数据
2015/05/06 21:07:29.206, INFO , TCPServer.run(146) mServerAlive = true mIsActive = true ==> 服务器端的 finally 中的验证log。。。从这里就不知道什么原因服务器端跳出了循环
2015/05/06 21:07:29.206, INFO , LnbSocket.run(125) this.GetConnectStatus() = 2
2015/05/06 21:07:29.206, INFO , TCPServer.SocketChannelClose(258) ServerSocket Close: java.nio.channels.SocketChannel[connected local=/127.0.0.1:58002 remote=/127.0.0.1:55294]
2015/05/06 21:07:29.206, INFO , TCPServer.SocketChannelClose(258) ServerSocket Close: sun.nio.ch.ServerSocketChannelImpl[/0.0.0.0:58002] ==> 关闭服务器端连接
2015/05/06 21:07:29.206, SEVERE , TCPClient.run(188) IOException NG: 服务器端被终止了
2015/05/06 21:07:29.206, INFO , TCPClient.Disconnect(302) ClientSocket Disconnect : IpAddress=127.0.0.1 PortNumber=58002
2015/05/06 21:07:29.206, SEVERE , TCPServer.SocketChannelClose(242) IOException NG : null
2015/05/06 21:07:29.206, INFO , Transaction.FreeTransaction(69) Transaction free
2015/05/06 21:07:29.206, INFO , TCPClient.run(218) ClientSocket End
...全文
236 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenjing0320 2015-05-07
  • 打赏
  • 举报
回复
2015/05/06 21:07:29.206, SEVERE , TCPServer.SocketChannelClose(242) IOException NG : null 这句报IOException了啊,你光把e.getMessage()打出来,message是null,没有堆栈信息什么都看不出来。 把e.getMessage()改成e.printStackTrace(),问题肯定一下就找出来了。
chenjing0320 2015-05-07
  • 打赏
  • 举报
回复
肯定是循环里抛异常了,不信你就把捕获IOException的地方改成e.printStackTrace()看看。 LoggerUtil.putErrorLog和LoggerUtil.putLog这两种打印日志的顺序应该是不确定的。
天弈isai 2015-05-07
  • 打赏
  • 举报
回复
引用 1 楼 chenjing0320 的回复:
2015/05/06 21:07:29.206, SEVERE , TCPServer.SocketChannelClose(242) IOException NG : null 这句报IOException了啊,你光把e.getMessage()打出来,message是null,没有堆栈信息什么都看不出来。 把e.getMessage()改成e.printStackTrace(),问题肯定一下就找出来了。
这个是进入到server的finally ,关闭SocketChannel的时候报错,输出的异常信息,问题是这场运行的话不应该进入到finally里面。我现在是不知道为什么程序会进入到server的finally里面。 finally { LoggerUtil.putLog("mServerAlive = " + mServerAlive + " mIsActive = " + mIsActive); if (mServerAlive) { // 愗抐張棟偑峴傢傟偰偄側偄応崌丅 SocketChannelClose(); } }

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧