C#仿QQ聊天程序(点对点无服务端)[易学网]
本程序是C#仿QQ程序的精简版,并做了大量优化处理,包括全新界面设计及删除部分冗余代码。
本程序是网络编程基础篇的最佳教材,其中关于动态分配端口,对象加密传输,消息处理,在线列表管理,
UI控制,系统配置,接口设计等技术值得学习。
用户在线管理器图,点右键弹出菜单 换肤功能演示:
用户在线管理器图,显示所有用户列表: 按部门用户分组:
对话窗体,可以显示和隐藏聊天记录,下图是[公司老总]和[喜羊羊]的对话记录。
打开了5个程序实例用于测试,模仿5个不同IP的客户端。当收到消息时任务栏图标志会闪烁。
下面介绍几个核心类及接口:
1.用户在线列表接口
代码
/// <summary>
/// 用户在线列表接口
/// </summary>
public interface IConnectionList
{
/// <summary>
/// 批量添加用户列表。
/// </summary>
/// <param name="connList"></param>
void AddConnection(IList connList);
/// <summary>
/// 添加一个用户连接
/// </summary>
/// <param name="conn"></param>
void AddConnection(ChatConnection conn);
/// <summary>
/// 在指定位置插入用户连接
/// </summary>
/// <param name="position"></param>
/// <param name="conn"></param>
void AddConnection(int position, ChatConnection conn);
/// <summary>
/// 删除一个用户连接
/// </summary>
/// <param name="account"></param>
void RemoveConnection(string account);
/// <summary>
/// 检查该用户是否在用户列表之中
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
bool IsConnectionExists(string account);
/// <summary>
/// 设置指定用户状态
/// </summary>
/// <param name="account"></param>
/// <param name="state"></param>
void SetConnectionState(string account, ChatState state);
/// <summary>
/// 当用户接受到消息,用户图标自动闪烁(如QQ那样跳动)
/// </summary>
/// <param name="account"></param>
void FlashConnection(string account);
/// <summary>
/// 停止跳动
/// </summary>
/// <param name="account"></param>
void StopFlash(string account);
/// <summary>
/// 关闭所有用户
/// </summary>
void CloseAll();
void CloseAll(bool removeUser);
/// <summary>
/// 增加接收到的消息,加入到聊天记录文件。
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
/// <returns></returns>
int AddReceivedMessage(string sender, string message);
/// <summary>
/// 返回所有连接
/// </summary>
/// <returns></returns>
IList GetConnections();
/// <summary>
/// 返回选中的用户
/// </summary>
/// <returns></returns>
ChatConnection GetSelectedConnection();
/// <summary>
/// 返回指定的用户连接 //易学原创作品,如转载请注明出处 by 易学网 www.vjsdn.net
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
ChatConnection GetConnection(string account);
/// <summary>
/// 显示用户类型(按部门或显示所有用户)
/// </summary>
ShowUser ShowUserType { get; set; }
}
2.发送消息窗体接口
代码
/// <summary>
/// 发送消息对话框接口
/// </summary>
public interface ISendMsgProxy
{
/// <summary>
/// 给发送消息窗体设置发送人和接收人
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
void SetConnection(ChatConnection from, ChatConnection to);
/// <summary>
/// 发送消息
/// </summary>
/// <param name="msg"></param>
void SendMessage(string msg);
/// <summary>
/// 接收人
/// </summary>
ChatConnection TargetConnection { get; }
/// <summary>
/// 发送人
/// </summary>
ChatConnection SenderConnection { get; }
/// <summary>
/// 显示消息
/// </summary>
/// <param name="type"></param>
/// <param name="msg"></param>
void ShowMessage(ShowMessageType type, string msg);
void ShowMessage(ShowMessageType type, ArrayList msgList);
/// <summary>
/// 显示窗体
/// </summary>
void ShowMe();
}
//易学原创作品,如转载请注明出处 by 易学网 www.vjsdn.net
3.用户资料及用户连线状态信息
代码
/// <summary>
/// 用户资料及用户连线状态信息
/// </summary>
public class ChatConnection
{
private string _DisplayName = string.Empty; //DisplayName
private string _Account = string.Empty; //Account
private string _IP = string.Empty; //联系人地址
private int _Port = -1;
private Image _PhotoIcon = null; //头像
private ChatState _State = ChatState.None;
private ArrayList _receivedMsg = new ArrayList(); //收到的消息
private string _FactoryCode = string.Empty;
//易学原创作品,如转载请注明出处 by 易学网 www.vjsdn.net
/// <summary>
/// 接受的信息
/// </summary>
public ArrayList ReceivedMessage { get { return _receivedMsg; } }
public ChatConnection() { }
public ChatConnection(string displayName, string account, string factoryCode, string ip, int port, ChatState state)
{
_Account = account;
_DisplayName = displayName;
_IP = ip;
_Port = port;
_State = state;
_FactoryCode = factoryCode;
}
/// <summary>
/// 用户头像
/// </summary>
public Image PhotoIcon
{
get { return _PhotoIcon; }
set { _PhotoIcon = value; }
}
/// <summary>
/// 连线状态
/// </summary>
public ChatState ConnectionState
{
get { return _State; }
set { _State = value; }
}
/// <summary>
/// 端口
/// </summary>
public int Port
{
get { return _Port; }
set { _Port = value; }
}
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName
{
get { return _DisplayName; }
set { _DisplayName = value; }
}
/// <summary>
/// 用户帐号
/// </summary>
public string Account
{
get { return _Account; }
set { _Account = value; }
}
public string FactoryCode
{
get { return _FactoryCode; }
set { _FactoryCode = value; }
}
/// <summary>
/// 用户IP地址
/// </summary>
public string IP
{
get { return _IP; }
set { _IP = value; }
}
public override string ToString()
{
return _DisplayName;
}
/// <summary>
/// 更新连线资料
/// </summary>
/// <param name="conn"></param>
public void Update(ChatConnection conn)
{
this.Account = conn.Account;
this.ConnectionState = conn.ConnectionState;
this.DisplayName = conn.DisplayName;
this.IP = conn.IP;
this.PhotoIcon = conn.PhotoIcon;
this.Port = conn.Port;
}
}
4. 消息定义(一个基类,及3个派生类)
代码
/// <summary>
/// 消息定义基类
/// </summary>
[Serializable]
public class cmdBase { }
//通知好友上线
[Serializable]
public class cmdNotifyOnline : cmdBase
{
private string _sender = string.Empty;
public string Sender { get { return _sender; } }
private int _Port = -1;
public int Port { get { return _Port; } }
private string _IP = string.Empty;
public string IP { get { return _IP; } }
private string _FactoryCode = string.Empty;
public string FactoryCode { get { return _FactoryCode; } }
private string _NickName = string.Empty;
public string NickName { get { return _NickName; } }
public cmdNotifyOnline(string sender, string ip, int port, string factory, string nickName)
{
_sender = sender;
_Port = port;
_IP = ip;
_FactoryCode = factory;
_NickName = nickName;
}
}
/// <summary>
/// 用户登出时通知所有用户删除连接
/// </summary>
[Serializable]
public class cmdExit : cmdBase
{
private string _sender = string.Empty;
public string Sender { get { return _sender; } }
public cmdExit(string sender)
{
_sender = sender;
}
}
/// <summary>
/// 普通消息
/// </summary>
[Serializable]
public class cmdMessage : cmdBase
{
private string _Content = string.Empty;//消息内容
private string _Sender = string.Empty;//发送人
public string Content { get { return _Content; } }
public string Sender { get { return _Sender; } }
public cmdMessage(string sender, string msg)
{
_Sender = sender;
_Content = msg;
}
}
//易学原创作品,如转载请注明出处 by 易学网 www.vjsdn.net