Java实现QQ附源码

/**
1,程序原理
Swing+事件监听+多线程+Socket通信
swing绘制界面;
事件监听:监听键盘和鼠标事件,用户操作鼠标或者键盘后就会触发绑定的代码;
多线程实现多个通信链接的处理;
Socket实现通信;
*/

===================================================================================================

/**
服务器端主要代码说明
1,MyServerFrame
public class MyServerFrame extends JFrame implements ActionListener {
 main(String[] args);
 MyServerFrame();
 actionPerformed(ActionEvent arg0);
}
MyServerFrame extends JFrame,继承JFrame就是画出一个窗口;
implements ActionListener就是添加监听事件,负责启动服务器MyQqServer;
main方法启动程序;
MyServerFrame()完成对窗口的设置,以及注册监听;
actionPerformed实现监听;
2,MyQqServer
MyQqServer{
 MyQqServer(){}
}
MyQqServer创建ServerSocket,监听客户端的连接请求;
客户端发出连接请求时,取出用户名和密码,密码等于"123456"时,就
创建一个线程SerConClientThread,让该线程与该客户端保持通讯;
并且将该线程交给ManageClientThread管理;
启动该线程;
通知其他线程,也就是通知其它在线用户.
3,SerConClientThread
public class SerConClientThread extends Thread{
 SerConClientThread(Socket s) {}
 // 让该线程去通知其它用户
 public void notifyOther(String iam){}
 run() {}
}
登录成功时run方法将已经登陆服务器的好友给该客户端返回;
客户端给好友发消息时,向对应的好友发送消息;
*/

===================================================================================================

/**
客户端主要实现类
1,QqClientLogin
public class QqClientLogin extends JFrame implements ActionListener{
 main(String[] args){}
 QqClientLogin(){}
 actionPerformed(ActionEvent arg0){}
}
Swing组件JFrame就是一个窗口,继承JFrame(extends JFrame)就是画出一个窗口;
implements ActionListener添加监听事件;
mian方法启动程序;
QqClientLogin方法初始化登陆界面;
actionPerformed方法实现鼠标和键盘的监听,将用户操作和对应的业务逻辑代码
绑定到一起;
输入用户名和密码后,用户点击登陆按钮时,去服务器验证;
登陆成功后,创建一个QQ客户端QqFriendList,并且将它加入到好友队列中进行管理,请求服务器
返回所有在线的好友;
2,QqFriendList
public class QqFriendList extends JFrame implements ActionListener,MouseListener{
 //初始化窗口
 QqFriendList(String ownerId){}
 //鼠标和键盘事件具体实现
 actionPerformed(ActionEvent arg0) {}
 mouseClicked(...){}
 
}
QqFriendList就是QQ主界面;
extends JFrame implements ActionListener,MouseListener这些也是为了创建窗口和添加键盘
和鼠标监听事件;
3,QqChat
public class QqChat extends JFrame implements ActionListener{
 //初始化窗口
 QqChat(String ownerId,String friend)
 //写一个方法,让它显示消息
 showMessage(Message m){}
 //监听实现
 actionPerformed(ActionEvent arg0){}
}
QqChat就是聊天窗口界面;
extends JFrame implements ActionListener 监听和创建窗口;
4,Message
public class Message implements java.io.Serializable{}
Message消息实体;
implements java.io.Serializable消息对象系列化是为了在网络上传输;
5,QqClientConServer
客户端连接服务器的后台;
6,ClientConServerThread
客户端和服务器端保持通讯的线程
**********************************************************************************
Serializable 作用
序列化的attribute,是为了利用序列化的技术
准备用于序列化的对象必须设置 [System.Serializable] 标签,该标签指示一个类可以序列化。
便于在网络中传输和保存
这个标签是类可以被序列化的特性,表示这个类可以被序列化。
什么叫序列化?
我们都知道对象是暂时保存在内存中的,不能用U盘考走了,有时为了使用介质转移对象,并且把对象的状态保持下来,就需要把对象保存下来,这个过程就叫做序列化,通俗点,就是把人的魂(对象)收伏成一个石子(可传输的介质)
什么叫反序列化?
就是再把介质中的东西还原成对象,把石子还原成人的过程。
在进行这些操作的时候都需要这个可以被序列化,要能被序列化,就得给类头加[Serializable]特性。
通常网络程序为了传输安全才这么做。
简介
序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。
在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进行一些权衡。只要您对此过程有足够的控制能力,就可以使该过程在很大程度上自动进行。例如,简单的二进制序列化不能满足需要,或者,由于特定原因需要确定类中那些字段需要序列化。以下各部分将探讨 .NET 框架提供的可靠的序列化机制,并着重介绍使您可以根据需要自定义序列化过程的一些重要功能。
持久存储
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。
公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。
当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。
按值封送
对象仅在创建对象的应用程序域中有效。除非对象是从 MarshalByRefObject 派生得到或标记为 Serializable,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。如果对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称为按值封送。
如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable。远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则(请参阅序列化过程的步骤)。
*/

*************************************************************************************

ServerSocket 所谓ServerSocket通信通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求.Socket和ServerSocket类库位于java.net包中.ServerSocket用于服务器端,ServerSocket通信是建立网络连接时使用的.在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话.对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服 务器端或在客户端而产生不同级别.不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的.
下面给出一个最简单的ServerSocket通信的例子供初学者参考:

服务器端:ServerDemo.java

Java代码

package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {

 /**
  * 注意:Socket的发送与接收是需要同步进行的,即客户端发送一条信息,服务器必需先接收这条信息, 而后才可以向客户端发送信息,否则将会有运行时出错
  */
 public static void main(String[] args) {
  ServerSocket ss = null;
  try {
   ss = new ServerSocket(8888);
   // 服务器接收到客户端的数据后,创建与此客户端对话的Socket
   Socket socket = ss.accept();
   // 用于向客户端发送数据的输出流
   DataOutputStream dos = new DataOutputStream(
     socket.getOutputStream());
   // 用于接收客户端发来的数据的输入流
   DataInputStream dis = new DataInputStream(socket.getInputStream());
   System.out.println("服务器接收到客户端的连接请求:" + dis.readUTF());
   // 服务器向客户端发送连接成功确认信息
   dos.writeUTF("接受连接请求,连接成功!");
   // 不需要继续使用此连接时,关闭连接
   socket.close();
   ss.close();
  } catch (IOException e) {

   e.printStackTrace();

  }
 }
}
ServerSocket通信客户端:ClientDemo.java
package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientDemo {
 public static void main(String[] args) {
  Socket socket = null;
  try {
   socket = new Socket("localhost", 8888);
   // 获取输出流,用于客户端向服务器端发送数据
   DataOutputStream dos = new DataOutputStream(
     socket.getOutputStream());
   // 获取输入流,用于接收服务器端发送来的数据
   DataInputStream dis = new DataInputStream(socket.getInputStream());
   // 客户端向服务器端发送数据
   dos.writeUTF("我是客户端,请求连接!");
   // 打印出从服务器端接收到的数据
   System.out.println(dis.readUTF());
   // 不需要继续使用此连接时,记得关闭哦
   socket.close();
  } catch (UnknownHostException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
 ==========================================================================================

效果图

 

 

==========================================================================================

完整源码

详见我的资源

http://download.csdn.net/detail/codehxy/7328567

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值