您的位置:首页 > 其它

我的第一款管理软件——————拥有界面的服务器

2016-03-28 23:00 295 查看
今天下午没有课,我用下午还有晚上的时间做好了左哥布置的练习————拥有界面的服务器。

首先,第一张图是没有打开服务之前的:



下面是我的截图,界面还有eclipse的控制台:



按了启动服务,服务器就启动好了。

自动生成IP地址和端口号。

然后用系统的控制台来控制来充当用户端,连接服务器。

做为测试,我连了三个。下图为测试:



用户名、IP、登录时间都正确,而且user1、4、8所发送的对话也可以在聊天框里面看到,最后要测试的功能是发送系统消息和关闭服务器。

测试结果如下:



关闭服务器后,出现了异常:



我觉得这是正常而且无法避免的,因为用户在使用用户端连接服务器的时候,socket是打开状态,突然关闭服务器,socket必然会断开,无服务器accept()。

而且用户在使用通信时,服务器管理人员突然手动断开服务器也是不太可能的(激动的时候除外)。

总而言之,我做的这一款拥有界面的服务器基本功能已经是实现了,所有的组件都拥有其相对应的功能。有很多的小bug没有处理,以后再做,因为现在已经是十点半了,我今天写了一个下午和晚上的代码,也有点烦躁了。


下面我总结介绍我做的代码:

首先,我先做了一个MyUserModel类implements-->TableModel接口

定义一个二维字符串容器用来存储用户登录的信息:用户名、IP地址、登录时间,然后用JTable来展现TableModel里面的信息。

public static String[][] userName = new String[11][3];//设置一个容器用来存放数据
public MyUserModel(){
userName[0][0] = "用户名";
userName[0][1] = "IP";
userName[0][2] = "登录时间";
}
public void addTableModelListener(TableModelListener l) {
//添加模型监听器()
}
public Class<?> getColumnClass(int columnIndex) {
return String.class;//设置模型类型String 类
}
public int getColumnCount() {
return 3;//获取列数
}
public String getColumnName(int columnIndex) {
return "";//获取列名
}

public int getRowCount() {
return 11;//获取行数
}
//获取模型数据
public Object getValueAt(int rowIndex, int columnIndex) {
return (String)userName[rowIndex][columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;//设置是否可编辑
}
public void removeTableModelListener(TableModelListener l) {
//移除监听器
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
userName[rowIndex][columnIndex] = (String)aValue;
}
然后再写一个界面的方法,把服务器的控制界面做出来:

public void FrameCode(){
/************************界面代码块************************/
this.setTitle("Test");
this.setSize(700, 300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
BorderLayout bl = new BorderLayout();
this.setLayout(bl);					//设置布局
JPanel North = new JPanel();		//创建上部面板North
IPString = new JTextField(15);
InferString = new JTextField(10);
IPlable = new JLabel("IP地址");
openServer = new JButton("启动服务");
openServer.setActionCommand("serverOpen");
Inputlable = new JLabel("端口号");
closeServer = new JButton("关闭服务");
closeServer.setActionCommand("serverClose");
North.add(IPlable);
North.add(IPString);
North.add(Inputlable);
North.add(InferString);
North.add(openServer);
North.add(closeServer);
this.add(North,bl.NORTH);			//把上部面板添加到界面上部
JPanel East = new JPanel();			//创建东部面板
BorderLayout ms = new BorderLayout();//创建一个版块面板,存放聊天信息和发送信息
East.setLayout(ms);
Msg = new JTextArea(20,20);
InputString = new JTextField(15);
send = new JButton("发送");
send.setActionCommand("send");
East.add(Msg,ms.CENTER);			//聊天框放在中间
JPanel Enen = new JPanel();			//在北边再设置一个流动面板,增加按钮和发送框的可视性
Enen.setLayout(new FlowLayout());
Enen.add(InputString);				//发送框和发送按钮放北边
Enen.add(send);
East.add(Enen, ms.SOUTH);
this.add(East,bl.EAST);
mm = new MyUserModel();//创建一个TestModel模型,放进JTable里面去展现
tb = new JTable(mm);
tb.setRowSelectionAllowed(false);//去掉水平的选择格子
tb.setRowHeight(20);
this.add(tb,bl.CENTER);

this.setVisible(true);			//界面可见
ma = new MyActionListener(openServer,closeServer,send,
IPString ,InferString,InputString,ss,Msg);
openServer.addActionListener(ma);
closeServer.addActionListener(ma);
send.addActionListener(ma);
}
其中的组件布局逻辑关系还是比较复杂的,但我在华信接近四个月的时间也不是全用来打乒乓球的,这点逻辑我还是比较容易理清的。

界面做出来后,我再一个个按钮组件、JTable、系统信息聊天框有条不紊的实现。

第一个是服务器启动按钮:

public void initFrame(){
try {
//telnet localhost 9090
//创建一个服务器对象,传入一个端口号,输出建立服务完成提示
//System.out.println("服务器的地址是: "+ss.getLocalSocketAddress());
this.FrameCode();
//创建了服务器同时,设置系统消息发送线程打开
Tool.sendSystemMsg();
while(true){
ss = ma.getServer();//不停的检测服务器是否已经在动作监听器里启动
if(ss!=null){//如果启动了服务器就可以连接客户端
System.out.println("已建立服务器");
//创建要接收服务的对象,获取套接字,获取服务,阻塞代码
Socket client = ss.accept();
//输出客户端地址
System.out.println("IP地址是:"+client.getRemoteSocketAddress());
ServerThread st = new ServerThread(client,tb,Msg);
//添加每一个客户端线程到socketlist容器中,方便群聊的实现
socketlist.add(st);
st.start();
}
}

} catch (Exception e) {
e.printStackTrace();
}
}
我用一个死循环,检测服务器是否已经启动,若是没有启动,就一直循环下去,一直到服务器启动然后到达:Socket client= ss.accept()这行阻塞代码。

服务器启动后,就是客户端的端口接入:

String str = "welcom !";
//从JFrame界面记录user登录情况
for(int i=0;i<MyUserModel.userName.length;i++){
if(MyUserModel.userName[i][0]==null){
MyUserModel.userName[i][0] = username;
MyUserModel.userName[i][1] = client.getLocalAddress().toString();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
MyUserModel.userName[i][2] = df.format(new Date());// new Date()为获取当前系统时间
tb.updateUI();
break;
}
}


接入在输出welcom!后,用TableModel里面的字符串容器来存储用户名、IP地址、登录时间,然后用JTable输出————————>>>>>这里我卡了十几分钟,因为JTable需要updata()后才可以显示Model里面的信息,长知识了,下次记住。

其中的当前时间输出我也是在百度上面摘录的。

最后的那个聊天框和系统消息就太简单了,直接就是输出就可以了。

Msg.append(username+":"+str+"\r\n");//聊天框发送当前输出信息
if(e.getActionCommand().equals("send")){
Msg.append("系统消息:"+InputString.getText()+"\r\n");
}
这就是我做得服务器控制界面的练习,新增了两个类:一个是监听器,一个是模型。

java面向对象的思想我也在做练习的时候越来越熟练,巩固了连连看那时候没有深入了解的TableModel接口。

十一点了,下线了,明天晚上我继续去华信学习,加油。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: