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

今天下午没有课,我用下午还有晚上的时间做好了左哥布置的练习————拥有界面的服务器。

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


下面是我的截图,界面还有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接口。

十一点了,下线了,明天晚上我继续去华信学习,加油。吐舌头




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值