同台服务器运行多个服务器监听程序出现端口冲突现象——单态模式惹的祸
服务器类
public abstract class ServerSocketFacade implements Runnable{
private int maxWait=5000;
private ServerSocket serverSocket;
private int port;
protected PooledConnectionHandle handle;
/**
*
* @param handle ConnectionHandle 处理连接的业务类,比如处理接受MT消息发送出去的类
* @throws IOException
*/
public ServerSocketFacade(PooledConnectionHandle handle,int maxWait,int port) throws IOException {
this.maxWait=maxWait;
this.port=port;
serverSocket = new ServerSocket(this.port);
serverSocket.setReceiveBufferSize(50*1024);
this.handle=handle;
System.out.println("构造函数\t端口号"+this.port);
}
/**
* 由具体的服务器类传递SOCKET连接给具体的业务类处理连接
* @param client Socket
* @param handle ConnectionHandle
*/
protected abstract void recieve(Socket client);
public void run(){
Socket client;
try {
System.out.println("设置超时时间\t"+this.maxWait);
this.serverSocket.setSoTimeout(this.maxWait);
}
catch (SocketException ex2) {
System.out.println("SocketException\t" + ex2.toString());
}
System.out.println("开始监听("+this.port+")……");
while (true) {
try {
client = this.serverSocket.accept();
recieve(client);
}
catch (SocketException ex1) {
System.out.println("SocketException\t" + ex1.toString());
}
catch (IOException ex) {
//System.out.println("IOException\t" + ex.toString());
}
}
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public void finalize(){
System.out.println("服务器停止");
}
}
处理连接的类
public abstract class ConnectionHandle implements Runnable{
private static LinkedList pool=new LinkedList();
public static int maxConnection=50;
public ConnectionHandle() {
}
//将SOCKET加入到队列中待处理
public static void processRequest(Socket socket){
synchronized(pool){
//超过了最大连接数则断开连接
if(pool.size()==maxConnection){
try {
socket.close();
}
catch (IOException ex) {
}
}
pool.add(pool.size(),socket);
pool.notifyAll();
}
}
protected abstract void handleConnection(Socket socket);
public void run(){
while(true){
synchronized(pool){
while(pool.isEmpty()){
try {
pool.wait();
}
catch (InterruptedException ex) {
}
}
//从队列中获取连接
Socket connection=(Socket)pool.removeFirst();
handleConnection(connection);
}
}
}
}
在单个服务器程序运行时效果不错,但是在启动了另外一个服务器进程以后,出现了网络请求混乱的现象,甚至怀疑是有其他非法程序在扫描攻击服务器程序。但是却发现数据协议格式相同,只是数据不正确,为此烦恼了好久。
后来无意之中发现
private static LinkedList pool=new LinkedList();
恍然大悟,原来如此。ConnectionHandle是一个抽象类,成员pool是一个静态变量,继承该类的所有子类都共享该成员pool,所以会导致所有的连接都跑到pool里面了,因此也就会出现上面的错误现象。
服务器类
public abstract class ServerSocketFacade implements Runnable{
private int maxWait=5000;
private ServerSocket serverSocket;
private int port;
protected PooledConnectionHandle handle;
/**
*
* @param handle ConnectionHandle 处理连接的业务类,比如处理接受MT消息发送出去的类
* @throws IOException
*/
public ServerSocketFacade(PooledConnectionHandle handle,int maxWait,int port) throws IOException {
this.maxWait=maxWait;
this.port=port;
serverSocket = new ServerSocket(this.port);
serverSocket.setReceiveBufferSize(50*1024);
this.handle=handle;
System.out.println("构造函数\t端口号"+this.port);
}
/**
* 由具体的服务器类传递SOCKET连接给具体的业务类处理连接
* @param client Socket
* @param handle ConnectionHandle
*/
protected abstract void recieve(Socket client);
public void run(){
Socket client;
try {
System.out.println("设置超时时间\t"+this.maxWait);
this.serverSocket.setSoTimeout(this.maxWait);
}
catch (SocketException ex2) {
System.out.println("SocketException\t" + ex2.toString());
}
System.out.println("开始监听("+this.port+")……");
while (true) {
try {
client = this.serverSocket.accept();
recieve(client);
}
catch (SocketException ex1) {
System.out.println("SocketException\t" + ex1.toString());
}
catch (IOException ex) {
//System.out.println("IOException\t" + ex.toString());
}
}
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public void finalize(){
System.out.println("服务器停止");
}
}
处理连接的类
public abstract class ConnectionHandle implements Runnable{
private static LinkedList pool=new LinkedList();
public static int maxConnection=50;
public ConnectionHandle() {
}
//将SOCKET加入到队列中待处理
public static void processRequest(Socket socket){
synchronized(pool){
//超过了最大连接数则断开连接
if(pool.size()==maxConnection){
try {
socket.close();
}
catch (IOException ex) {
}
}
pool.add(pool.size(),socket);
pool.notifyAll();
}
}
protected abstract void handleConnection(Socket socket);
public void run(){
while(true){
synchronized(pool){
while(pool.isEmpty()){
try {
pool.wait();
}
catch (InterruptedException ex) {
}
}
//从队列中获取连接
Socket connection=(Socket)pool.removeFirst();
handleConnection(connection);
}
}
}
}
在单个服务器程序运行时效果不错,但是在启动了另外一个服务器进程以后,出现了网络请求混乱的现象,甚至怀疑是有其他非法程序在扫描攻击服务器程序。但是却发现数据协议格式相同,只是数据不正确,为此烦恼了好久。
后来无意之中发现
private static LinkedList pool=new LinkedList();
恍然大悟,原来如此。ConnectionHandle是一个抽象类,成员pool是一个静态变量,继承该类的所有子类都共享该成员pool,所以会导致所有的连接都跑到pool里面了,因此也就会出现上面的错误现象。
回复Comments
作者:
{commentrecontent}