这是一个聊天室的服务器端。问题是:当启动此线程后,控制器就失去了作用,无法工作,怎样才能在点击控制器时,让服务器关闭(其实是关闭线程)。谢谢各位了,本人菜鸟。
详细代码如下:
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Server extends Frame implements ActionListener{
private Button BonY;
private Button BonN;
public Server(){
super("控制器");
this.setSize(320,120);
this.setBackground(java.awt.Color.lightGray);
this.setLocation(300,240);
this.setLayout(new java.awt.FlowLayout(FlowLayout.LEFT));
BonY=new Button("启动");
BonN=new Button("关闭");
this.add(BonY);
this.add(BonN);
BonY.addActionListener(this);
BonN.addActionListener(this);
this.addWindowListener(new WinClose());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==BonY)
{
new ChatServer();
if(e.getSource()==BonN){
new WinClose();
}
//实例化一个ChatServer类
}
}
public static void main(String arg[]){
new Server();
}
}
class WinClose implements WindowListener{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowOpened(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
}
class ChatServer { static int Port=6000; //端口号
static Vector Clients=new Vector(10); //存储连接客户信息
static ServerSocket SvSocket=null; //建立服务器socket
static Socket socket=null; //套接字连接 public ChatServer() {
try {
System.err.println("服务器启动");
SvSocket=new ServerSocket(Port); //初始化服务器套接字
while(true){
socket=SvSocket.accept(); //等待连接
System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
Client client=new Client(socket); //实例化一个客户线程
Clients.addElement(client); //增加客户线程到向量中
client.start(); //启动线程
NfChatRoom(); //监视聊天室连接变化
}
}
catch(Exception ex) {
ex.printStackTrace(); //输出出错信息
}
} public static void NfChatRoom() {
StringBuffer newUser=new StringBuffer("newUser");
for(int i=0;i<Clients.size();i++){
Client c=(Client)Clients.elementAt(i);
newUser.append(":"+c.name); //客户端姓名字符串
}
newUser.append(":"+"所有人");
SdClientMsg(newUser); //发送信息到客户端
} public static void SdClientMsg(StringBuffer message){
for(int i=0;i<Clients.size();i++){
Client client=(Client)Clients.elementAt(i); //分别得到每个客户端的连接
client.send(message); //发送信息
}
} public static void SdSlClient(StringBuffer msge,String Name){
for(int i=0;i<Clients.size();i++){
Client client=(Client)Clients.elementAt(i);
if(client.name.equals(Name)){
client.send(msge);
} }
}
public void closeAll() { //关闭所有连接
while(Clients.size()>0) { //遍历整个Vector
Client client=(Client)Clients.firstElement(); //得到一个客户端
try{
client.socket.close(); //关闭端口
}
catch(IOException ex){
ex.printStackTrace(); //输出错误信息
}
Clients.removeElement(client); //移出客户端信息
}
}
public static void disconnect(Client c){ //断开客户端
try{
System.err.println(c.ip+"断开连接q\n");
c.send(new StringBuffer("Quit")); //向客户发送断开连接信息
c.socket=null; //关闭端口
}
catch(Exception ex){
ex.printStackTrace();
}
Clients.removeElement(c); //移出客户端信息
}
class Client extends Thread {
Socket socket; //连接端口
String name; //用户姓名
String ip; //客户端IP地址
BufferedReader reader ; //输入流
PrintStream ps; //输出流 public Client(Socket s){
socket=s;
try{
reader = new BufferedReader(new InputStreamReader(s.getInputStream())); //得到输入流
ps=new PrintStream(s.getOutputStream()); //得到输出流
String info=reader.readLine(); //读取接受到的信息
StringTokenizer stinfo=new StringTokenizer(info,":"); //分解字符串
String head=stinfo.nextToken(); //获取关键字
if(stinfo.hasMoreTokens())
name=stinfo.nextToken(); //获取昵称
if(stinfo.hasMoreTokens())
ip=stinfo.nextToken(); //获取IP地址
}
catch(IOException ex){
ex.printStackTrace();
}
} public void send(StringBuffer msg) {
ps.println(msg); //输出信息
ps.flush();
} public void run(){
while(true){
String line=null;
try{
line=reader.readLine(); //读取数据流
}
catch(IOException ex){
ex.printStackTrace(); //输出错误信息
ChatServer.disconnect(this); //断开连接
ChatServer.NfChatRoom(); //更新信息
return;
} if(line==null){ //客户离开
ChatServer.disconnect(this);
ChatServer.NfChatRoom();
return;
} StringTokenizer st=new StringTokenizer(line,":"); //分解字符串
String keyword=st.nextToken(); if(keyword.equals("Connect")){ //发送来的是聊天信息
StringBuffer msg=new StringBuffer("Connect:");
msg.append(name); //在信息上增加用户名
msg.append(st.nextToken("\0"));
ChatServer.SdClientMsg(msg); //发送聊天语句到各个客户端
}
else if(keyword.equals("ConnectSl")){
String SlName = st.nextToken();
String SlMsg = st.nextToken("\0");
StringBuffer msg=new StringBuffer("Connect:");
msg.append(name+" 对你说");
msg.append(SlMsg);
ChatServer.SdSlClient(msg,SlName);
StringBuffer msg1=new StringBuffer("Connect:");
msg1.append("你对 "+SlName+" 说");
msg1.append(SlMsg);
ChatServer.SdSlClient(msg1,name);
}
else if(keyword.equals("Quit")){ //退出命令
ChatServer.disconnect(this); //断开连接
ChatServer.NfChatRoom(); //刷新信息
}
}
}
}
}
详细代码如下:
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Server extends Frame implements ActionListener{
private Button BonY;
private Button BonN;
public Server(){
super("控制器");
this.setSize(320,120);
this.setBackground(java.awt.Color.lightGray);
this.setLocation(300,240);
this.setLayout(new java.awt.FlowLayout(FlowLayout.LEFT));
BonY=new Button("启动");
BonN=new Button("关闭");
this.add(BonY);
this.add(BonN);
BonY.addActionListener(this);
BonN.addActionListener(this);
this.addWindowListener(new WinClose());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==BonY)
{
new ChatServer();
if(e.getSource()==BonN){
new WinClose();
}
//实例化一个ChatServer类
}
}
public static void main(String arg[]){
new Server();
}
}
class WinClose implements WindowListener{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowOpened(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
}
class ChatServer { static int Port=6000; //端口号
static Vector Clients=new Vector(10); //存储连接客户信息
static ServerSocket SvSocket=null; //建立服务器socket
static Socket socket=null; //套接字连接 public ChatServer() {
try {
System.err.println("服务器启动");
SvSocket=new ServerSocket(Port); //初始化服务器套接字
while(true){
socket=SvSocket.accept(); //等待连接
System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
Client client=new Client(socket); //实例化一个客户线程
Clients.addElement(client); //增加客户线程到向量中
client.start(); //启动线程
NfChatRoom(); //监视聊天室连接变化
}
}
catch(Exception ex) {
ex.printStackTrace(); //输出出错信息
}
} public static void NfChatRoom() {
StringBuffer newUser=new StringBuffer("newUser");
for(int i=0;i<Clients.size();i++){
Client c=(Client)Clients.elementAt(i);
newUser.append(":"+c.name); //客户端姓名字符串
}
newUser.append(":"+"所有人");
SdClientMsg(newUser); //发送信息到客户端
} public static void SdClientMsg(StringBuffer message){
for(int i=0;i<Clients.size();i++){
Client client=(Client)Clients.elementAt(i); //分别得到每个客户端的连接
client.send(message); //发送信息
}
} public static void SdSlClient(StringBuffer msge,String Name){
for(int i=0;i<Clients.size();i++){
Client client=(Client)Clients.elementAt(i);
if(client.name.equals(Name)){
client.send(msge);
} }
}
public void closeAll() { //关闭所有连接
while(Clients.size()>0) { //遍历整个Vector
Client client=(Client)Clients.firstElement(); //得到一个客户端
try{
client.socket.close(); //关闭端口
}
catch(IOException ex){
ex.printStackTrace(); //输出错误信息
}
Clients.removeElement(client); //移出客户端信息
}
}
public static void disconnect(Client c){ //断开客户端
try{
System.err.println(c.ip+"断开连接q\n");
c.send(new StringBuffer("Quit")); //向客户发送断开连接信息
c.socket=null; //关闭端口
}
catch(Exception ex){
ex.printStackTrace();
}
Clients.removeElement(c); //移出客户端信息
}
class Client extends Thread {
Socket socket; //连接端口
String name; //用户姓名
String ip; //客户端IP地址
BufferedReader reader ; //输入流
PrintStream ps; //输出流 public Client(Socket s){
socket=s;
try{
reader = new BufferedReader(new InputStreamReader(s.getInputStream())); //得到输入流
ps=new PrintStream(s.getOutputStream()); //得到输出流
String info=reader.readLine(); //读取接受到的信息
StringTokenizer stinfo=new StringTokenizer(info,":"); //分解字符串
String head=stinfo.nextToken(); //获取关键字
if(stinfo.hasMoreTokens())
name=stinfo.nextToken(); //获取昵称
if(stinfo.hasMoreTokens())
ip=stinfo.nextToken(); //获取IP地址
}
catch(IOException ex){
ex.printStackTrace();
}
} public void send(StringBuffer msg) {
ps.println(msg); //输出信息
ps.flush();
} public void run(){
while(true){
String line=null;
try{
line=reader.readLine(); //读取数据流
}
catch(IOException ex){
ex.printStackTrace(); //输出错误信息
ChatServer.disconnect(this); //断开连接
ChatServer.NfChatRoom(); //更新信息
return;
} if(line==null){ //客户离开
ChatServer.disconnect(this);
ChatServer.NfChatRoom();
return;
} StringTokenizer st=new StringTokenizer(line,":"); //分解字符串
String keyword=st.nextToken(); if(keyword.equals("Connect")){ //发送来的是聊天信息
StringBuffer msg=new StringBuffer("Connect:");
msg.append(name); //在信息上增加用户名
msg.append(st.nextToken("\0"));
ChatServer.SdClientMsg(msg); //发送聊天语句到各个客户端
}
else if(keyword.equals("ConnectSl")){
String SlName = st.nextToken();
String SlMsg = st.nextToken("\0");
StringBuffer msg=new StringBuffer("Connect:");
msg.append(name+" 对你说");
msg.append(SlMsg);
ChatServer.SdSlClient(msg,SlName);
StringBuffer msg1=new StringBuffer("Connect:");
msg1.append("你对 "+SlName+" 说");
msg1.append(SlMsg);
ChatServer.SdSlClient(msg1,name);
}
else if(keyword.equals("Quit")){ //退出命令
ChatServer.disconnect(this); //断开连接
ChatServer.NfChatRoom(); //刷新信息
}
}
}
}
}
while(true),写成while(isrunning).需要关闭的时候,将isrunning置为false即可
这句的前面,加上:
SvSocket.setSoTimeout(5000);
然后在程序中设置一个boolean型的标志位。程序写成while(标志位)。
在你想终止服务的地方,去设置标志位为false。
这样,你的pg就有机会去验证这个标志了。
如果这样改的话,你还要做一些异常处理。因为如果连接超时的话,是会抛出异常的。你应该捕获这个异常,然后重新进入循环。
// do more work;
}}其他线程只要调用t.interrupted(),就能将线程t的中断状态置位,然后t线程的run中循环就会结束了。
boolean isrunning=true;
public void windowClosed(WindowEvent e){
isrunning=false;
}
while(isrunning){
}