基于socket(TCP)的聊天程序(C/S结构)

这个是我们网络与通信的作业。当初看作业题的时候感觉这题是要我们熟悉TCP连接,不过后面跟了很多很烦的要求,比如一定要有GUI,要验证用户登录,要给出当前用户的列表,要能给所有人发信息,要能给指定的人发信息。然后我又用java作为语言,socket的类本来就封装好的,所以整个主题就偏掉了,更像是java多线程编程联系。而且我觉得,我整一个编程菜鸟。程序结构乱七八糟,算法乱七八糟,而且编程很磨叽,编了好几天才完成这个程序。多线程的问题确实搞的我头很大,有时候不得不动用一些山寨方法避免问题。

看了别人编的程序,大多只有两个文件,一个server,一个client。我本来为了程序结构清晰一点,多建了几个,结果到了后面越来越烦了。

整个C/S的运作方式是这样的:server建立之后,等待client连接。client启动之后,连接到服务器的socket,第一步是向服务器发送用户名和密码。服务器连接后的第一步是产生一个监听线程,然后监听到客户端发过来的用户名密码做验证,如果验证通过,则向客户端发送connected的信号,然后将该socket加入到一个arraylist中方便以后管理,如果没通过,就向客户端发送failed信号。客户端在接收到connected信号之后,开启新的监听线程监听服务器发来的别的信息。客户端能做到向所有人发送一个信息以及向特定的一个人发送信息。用的方法很山寨,就是在信息前面加个头,比如说sta:或者stu:,分别表示向所有人发送和向某人发送。服务器接收到这个信息之后,先要解析信息的首部,然后再执行相应的操作。

我之前为了让程序层次分明一点,把客户端分为两层,一层是核心层,就是ClientKernel这个文件,它封装了所有客户端的功能,和服务器通信的实体也是它,另外一层是客户端实体,只要调用一下ClientKernel的函数就可以实现功能了,这样做的好处是可移植性,可以做命令行的客户端,也可以做GUI的客户端,其实是模仿twitter4j这样的库,不过后来发现做的很烂啊。另外,为了做到有新用户登录或者用户退出时,所有用户的userlist列表都能自动刷新,而客户端实体又和kernel分离,就用了一个接口起到类似回调函数的作用。

另外,我的英文很差,所以几乎所有的变量名都是乱起的。另另外,我对java的异常捕获不是很了解,所以都是瞎捕获的。另另另外,在线程方面我可能遇到了一点问题,为了避免这些问题,有些io流创建了就没有关闭,这个实在很难解决。

下面给出代码:

Server.java:

 

UserController.java:

User.java:

 

ClientKernel.java:

 

ClientOpt.java(这个名字起错了,应该是指实体客户端要有的操作):

 

 

 

GUI代码太长,不给出了。

 

 

 

 

No Comments

Post a Comment