参考别人研究的QQ协议做的简单的WPF版手机QQ聊天器,界面不太美观!

简单功能:

1.登陆
2.消息查看器
3.托盘消息闪烁
4.查看个人基本资料
5.聊天
6.点击闪烁图标与最近的好友聊天

截图


主要通讯核心类:(有些是参考的网上的,基本上自己都改动过)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading;
using My.Properties;namespace My
{/// <summary>/// 获取腾讯QQ数据操作类/// </summary>public class ServerPostProcess{private string num = string.Empty;  //构造函数的QQ号码private string pwd = string.Empty; //构造函数的QQ密码private string md5Pwd = string.Empty;//加密后的QQ密码public string[] online_Face = { "" };       //在线的头像号码public string[] online_Station = { "" };    //在线的状态public string[] online_Number = { "" };     //在线的号码public string[] online_NameK = { "" };      //在线的昵称private WebClient wc1 = null;private WebClient wc2 = null;private WebClient wc3 = null;#region WebClient操作池(暂时放弃)出现_clientSends并发问题//private List<WebClient> _clientSends = new List<WebClient>(3); <summary>尝试从集合里面拿到一个发送器</summary>//private WebClient ClientSends//{//    get {//        lock (_clientSends)//        {//            int tnum = GetClientSendsNoBusyNum;//            if (_clientSends.Count <= 5 && tnum <= 0)//            {//                WebClient addWc = new WebClient();//                _clientSends.Add(addWc);//                return addWc;//            }//            if (tnum == 0)//            {//                return null;//            }//            //拿出一个不繁忙的发送器进行处理请求//            foreach (WebClient wct in _clientSends)//            {//                if (wct != null && !wct.IsBusy)//                {//                    return wct;//                }//            }//            return null;//        }//    }//}/ <summary>/ 获取发送器不繁忙的可用数量/ </summary>//private int GetClientSendsNoBusyNum//{//    get//    {//        int i = 0;//        foreach (WebClient wc in _clientSends)//        {//            if (wc != null && !wc.IsBusy)//            {//                i++;//            }//        }//        return i;//    }//} #endregionprivate string postStr;     //发送给服务器的字符串private byte[] postArray;   //把要发送的字符串变成字符数组private byte[] returnArray;  //接受服务器返回的字符数组private string returnStr;    //把返回的字符数组变成字符串public string[] MT;    //储存信息类型public string[] UN;    //储存信息来源号码public string[] MG;    //储存信息内容public bool is_RightLogin;//是否正确的登陆/// <summary>/// 登陆前提:必须通过验证/// </summary>public ServerPostProcess(){Users user = ManagerStaticResouce.LoginingUser;if (user != null){num = user.Uid;pwd = user.Pwd;}else{throw new Exception("用户名称不存在!");}wc1 = new WebClient();wc2 = new WebClient();wc3 = new WebClient();md5Pwd = MD5(pwd);}/// <summary>/// 向服务器POST数据/// </summary>private bool UploadData(int type){try{WebClient wc = GetClientSends(type);//尝试拿到一个发送器if (wc != null)//双重判断{returnArray = wc.UploadData("http://tqq.tencent.com:8000", "POST", postArray);}else{return false;}}catch (Exception ex){throw new WebException(ex.Message);}return true;}/// <summary>/// 得到一个发送器/// </summary>/// <param name="type">操作类型(1 其他,2 发送消息,3 获取消息)</param>/// <returns></returns>private WebClient GetClientSends(int type){if (wc1 != null && !wc1.IsBusy && type == 1){return wc1;}else if (wc2 != null && !wc2.IsBusy && type == 2){return wc2;}else if (wc3 != null && !wc3.IsBusy && type==3){return wc3;}else{return null;}}/// <summary>/// 登陆QQ/// </summary>/// <returns>登陆成功就返回True</returns>public bool QQ_Login(ref string returnResult){postStr = "VER=1.1&CMD=Login&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7)+ "&UIN=" + num + "&PS=" + md5Pwd + " &M5=1&LC=9326B87B234E7235";postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){returnResult = "服务器忙!请重新点击登陆!";return false;}returnStr = Encoding.UTF8.GetString(returnArray);returnResult = returnStr;if (returnStr.Contains("RES=0&RS=0")){is_RightLogin = true;return true;}else{return false;}}/// <summary>/// QQ退出登陆,并改变is_RightLogin为False/// </summary>public void QQ_Logout(){postStr = "VER=1.1&CMD=Logout&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据while (true){if (!UploadData(1)){continue;}break;}returnStr = Encoding.UTF8.GetString(returnArray);if (returnStr.Contains("&RES=0")){is_RightLogin = false;return;}}/// <summary>/// MD5加密/// </summary>/// <param name="toCryString"></param>/// <returns></returns>public static string MD5(string toCryString){//using System.Security.Cryptography安全.密码系统MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();//asp是小写,把所有字符变小写string tmp =BitConverter.ToString(hashmd5.ComputeHash(Encoding.UTF8.GetBytes(toCryString))).Replace("-", "").ToLower();hashmd5.Clear();return tmp;}/// <summary>/// 获取QQ好友列表/// </summary>/// <returns>返回一个字符串数组,数组最后一个元素是空格</returns>public string[] QQ_List(){postStr = "VER=1.1&CMD=List&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&TN=160&UN=0";postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return null;}returnStr = Encoding.UTF8.GetString(returnArray);if (!returnStr.Contains("&RES=0"))is_RightLogin = false;string s2 = returnStr.Remove(0, returnStr.IndexOf("&UN=") + 4);string[] QQ_Friend_List = s2.Split(',');return QQ_Friend_List;}/// <summary>/// 更新QQ类中目前在线online_四个字符串数组的值/// </summary>public void QQ_Query_Stat(){postStr = "VER=1.1&CMD=Query_Stat&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&TN=50&UN=0";postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return;}returnStr = Encoding.UTF8.GetString(returnArray);if (!returnStr.Contains("&RES=0"))is_RightLogin = false;StringBuilder sb = new StringBuilder(returnStr);sb.Remove(returnStr.IndexOf("&FN="), returnStr.Length - returnStr.IndexOf("&FN="));sb.Remove(0, returnStr.IndexOf("&FC=") + 4);online_Face = sb.ToString().Split(',');sb = new StringBuilder(returnStr);sb.Remove(returnStr.IndexOf("&UN="), returnStr.Length - returnStr.IndexOf("&UN="));sb.Remove(0, returnStr.IndexOf("&ST=") + 4);online_Station = sb.ToString().Split(',');sb = new StringBuilder(returnStr);sb.Remove(returnStr.IndexOf("&NK="), returnStr.Length - returnStr.IndexOf("&NK="));sb.Remove(0, returnStr.IndexOf("&UN=") + 4);online_Number = sb.ToString().Split(',');string ss = returnStr.Remove(0, returnStr.IndexOf("&NK=") + 4);online_NameK = ss.Split(',');}/// <summary>/// 输入一个QQ号,查询这个QQ号的信息/// </summary>/// <param name="search_num">输入一个QQ号,查询该QQ信息</param>/// <returns>字符串数组(0联系地址,1用户年龄,2用户邮箱,3头像,4个人网站,5职业,6邮箱,7联系电话,8简介,9省份,10真实姓名,11毕业院校,12性别,13QQ号,14昵称)</returns>public string[] QQ_GetInfo(string search_num){postStr = "VER=1.1&CMD=GetInfo&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&LV=2&UN=" + search_num;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return null;}returnStr = Encoding.UTF8.GetString(returnArray);if (!returnStr.Contains("&RES=0"))is_RightLogin = false;MatchCollection matches = Regex.Matches(returnStr, "&([^=][^=])=([^&]*)");List<string> Info = new List<string>();for (int i = 0; i < matches.Count; i++)Info.Add(matches[i].Groups[2].ToString());Info.RemoveAt(6);   //去除LV=多少, 这表示查询方式,默然就是普通查询if (Info[12].ToString() == "0")Info[12] = "男";elseInfo[12] = "女";string[] Inf = Info.ToArray();return Inf;}/// <summary>/// 添加好友功能/// </summary>/// <param name="fir_num">输入一个QQ号,请求加为好友</param>/// <returns>0表示已经加为好友,1表示需要验证请求,2表示拒绝</returns>public string AddToList(string fir_num){postStr = "VER=1.1&CMD=AddToList&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&UN=" + fir_num;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return null;}returnStr = Encoding.UTF8.GetString(returnArray);if (!returnStr.Contains("&RES=0"))is_RightLogin = false;MatchCollection matchs = Regex.Matches(returnStr, "&CD=(.)");return matchs[0].Groups[1].ToString();}/// <summary>/// 回应加为好友的响应/// </summary>/// <param name="fri_Num">请求的QQ号码</param>/// <param name="agree_Type">0表示通过验证,1表示拒绝对方,2表示请求加对方为好友</param>public void Ack_AddToList(string fri_Num, string agree_Type){postStr = "VER=1.1&CMD=Ack_AddToList&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&UN=" + fri_Num + "&CD=" + agree_Type + "&RS=";postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return;}returnStr = Encoding.UTF8.GetString(returnArray);if (!returnStr.Contains("&RES=0"))is_RightLogin = false;}/// <summary>/// 删除好友,成功返回True/// </summary>/// <param name="del_num">输入一个QQ号,删除这个QQ好友</param>/// <returns></returns>public bool DelFromList(string del_num){postStr = "VER=1.1&CMD=DelFromList&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&UN=" + del_num;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return false;}returnStr = Encoding.UTF8.GetString(returnArray);if (returnStr.Contains("&RES=0"))return true;elsereturn false;}/// <summary>/// 改变QQ当前状态(在线,离线,忙碌)/// </summary>/// <param name="Stat">输入10在线,20离线,30忙碌</param>/// <returns></returns>public bool Change_Stat(string stat){postStr = "VER=1.1&CMD=Change_Stat&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&ST=" + stat;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(1)){return false;}returnStr = Encoding.UTF8.GetString(returnArray);if (returnStr.Contains("&RES=0"))return true;elsereturn false;}/// <summary>/// 向一个QQ号码发送消息/// </summary>/// <param name="msgTo">输入一个QQ号,向他发送消息</param>/// <param name="msg">输入消息内容</param>/// <returns>成功返回True</returns>public bool QQ_SendMsg(string msgTo, string msg){postStr = "VER=1.2&CMD=CLTMSG&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num + "&UN=" + msgTo + "&MG=" + msg;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(2)){return false;}returnStr = Encoding.UTF8.GetString(returnArray);if (returnStr.Contains("&RES=20")){is_RightLogin = false;return false;}if (returnStr.Contains("&RES=0"))return true;elsereturn false;}//待处理public void GetMsgEx(){postStr = "VER=1.1&CMD=GetMsgEx&SEQ=" + DateTime.Now.Ticks.ToString().Substring(7, 7) + "&UIN=" + num;postArray = System.Text.Encoding.UTF8.GetBytes(postStr);//向服务器POST数据if (!UploadData(3)){return;}returnStr = Encoding.UTF8.GetString(returnArray);if (returnStr.Contains("\r"))returnStr = returnStr.Replace("\r", "\n");if (returnStr.Contains("&RES=0") && returnStr.Contains("&MN=")){is_RightLogin = true;MatchCollection matches = Regex.Matches(returnStr, "&MN=([^&]*)");if (matches[0].Groups[1].ToString() != "0") //判断返回的信息数量是否为0条{matches = Regex.Matches(returnStr, "&MT=([^&]*)&UN=([^&]*)&MG=([^&]*)");MT = matches[0].Groups[1].ToString().Split(',');   //信息类型UN = matches[0].Groups[2].ToString().Split(',');   //信息来源号码returnStr = returnStr.Remove(0, returnStr.IndexOf("&MG=") + 4);MG = returnStr.Split(',');   //信息内容//将消息内容进行转码for (int i = 0; i < MG.Length - 1; i++){MG[i] = MG[i].Replace("%25", "%");MG[i] = MG[i].Replace("%26", "&");MG[i] = MG[i].Replace("%2c", ",");}}else{MT = null;UN = null;MG = null;is_RightLogin = false;}}else{MT = null;UN = null;MG = null;is_RightLogin = false;}}}
}

此程序纯属好玩,单纯的只想研究下手机QQ的协议.
注意没有使用过手机登陆过QQ的用户可能无法正常登陆,解决办法是使用真正的手机QQ登陆一次即可.
程序下载:NatureQQ
源码下载:NatureQQ_Source

转载于:https://www.cnblogs.com/NatureSex/archive/2011/09/05/2167437.html

WPF界面-手机QQ_DEMO相关推荐

  1. WPF界面MahApps.Metro之应用

    大家都知道,经常干后端的程序猿通常不善于设计前端界面,来个界面的活,要么傻眼了,要么花大力气自己去做组件,费时费力,效果不好.好的程序首先要"长得漂亮",赏心悦目的界面可以提升应用 ...

  2. WPF界面设计技巧(3)—实现不规则动画按钮

    WPF界面设计技巧(3)-实现不规则动画按钮 原文:WPF界面设计技巧(3)-实现不规则动画按钮 发布了定义WPF按钮的教程后,有朋友问能否实现不规则形状的按钮,今天我们就来讲一下不规则按钮的制作. ...

  3. 准备.Net转前端开发-WPF界面框架那些事,UI快速实现法

    题外话 打开博客园,查看首页左栏的"推荐博客",排名前五的博客分别是(此处非广告):Artech.小坦克.圣殿骑士.腾飞(Jesse).数据之巅.再看看它们博客的最新更新时间:Ar ...

  4. WPF 界面提示加载出错

    当WPF界面代码中包含多个 VisualStateManager.VisualStateGroups 时会导致界面无法正常显示,把这些代码注释掉就可以展示出界面. 转载于:https://www.cn ...

  5. 如何在Revit中引入WPF界面(通俗易懂)

    欢迎加入BIM行业开发交流1群 群号:711844216(满),二群群号:1016453207 背景 小伙伴们在做revit二次开发时,为了丰富开发内容,会有引入界面的需求.作为窗体程序开发,基本上有 ...

  6. SpringBoot项目H5界面手机拍照调用腾讯云OCR卡证识别接口完整例子

    最近一个微信端项目的功能涉及一个手机拍照上传身份证识别身份证信息回显的功能,调用的接口是腾讯云OCR的卡证识别功能.看了腾讯云的api通俗易懂,本地写好了demo测试可用.H5界面手机拍照调用后台方法 ...

  7. 【.Net码农】WPF界面设计—撸大师

    http://blog.csdn.net/cmis7645/article/details/7562833 WPF界面设计,模仿了金山卫士,360,鲁大师的界面! [html] view plainc ...

  8. .NET都实现平台统一了你还不会WPF界面设计?

    WPF界面设计基础 布局 常用布局属性 常用布局容器 Grid StackPanel WrapPanel DockPanel UniformGrid 控件结构 样式 触发器 触发器的类型: 控件模板- ...

  9. WPF - 界面美化 MahApps.Metro UI

    WPF - 界面美化 MahApps.Metro UI 欢迎使用MahApps.Metro 我的接入效果 接入方式 欢迎使用MahApps.Metro MahApps.Metro资料: 官网地址:ht ...

最新文章

  1. 洛谷P1417 烹调方案
  2. 每日一皮:上线一切正常的顺畅感就是如此赏心悦目!
  3. .Net版行号消除器
  4. 谁是最强的女汉子_JAVA
  5. 网络配置及shell基础
  6. leetCode刷题-第二题两数之和
  7. 计算机二级考试题停车收费,计算机二级考试真题-Excel-停车场调整收费标准
  8. 盛金公式解一元三次方程_【国际数学竞赛】高次方程求根
  9. C#中的函数参数能不能有默认值的解决方法
  10. Android之back键拦截处理
  11. BI/数据仓库/数据分析 基础入门:一些常见概念解释
  12. ubuntu桌面美化mac_Ubuntu16.04 主题美化
  13. Windows Server 2012安装vc++组件失败
  14. 笔试题: 数据库 已看1 一些关键的sql语句练习 和选择题 有用 sql语句练习 挺好...
  15. 【开源项目分享】GitHub中文排行榜 - 帮助你发现高分优秀中文项目-Java
  16. python下的一个好用的日历库,支持农历和公历互转,是一个很好用的日期包
  17. 使用 Python 进行面部识别
  18. Python - 学习/实践
  19. 计算机毕业设计JAVA电影推荐网站mybatis+源码+调试部署+系统+数据库+lw
  20. 面部皮肤200种问题_颧骨内推真那么吓人?这是一篇耗时200个小时的功课

热门文章

  1. 微信小程序—收藏功能
  2. PO*创建标准采购订单
  3. ccd坏点测试软件,如何测试CCD坏点(ZT)
  4. Python爬取王者荣耀所有英雄以及高清大图
  5. 取整函数,back函数,memset函数,sizeof函数,--LeetCode刷题笔记3
  6. 面试宝典(一) - 让你不再错过“金九银十“的求职浪潮之简历包装篇
  7. 5G NGC — NRF 网络注册功能
  8. linux音频子系统 - DAPM
  9. 高中生参加的计算机奥赛是,电脑奥赛中最寂寥的竞赛 5学生夺牌直通清华
  10. 新手做数据分析的5大误区,一定要避开!