博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
替换Srun3000解决掉网问题
阅读量:7231 次
发布时间:2019-06-29

本文共 5749 字,大约阅读时间需要 19 分钟。

  上次写了篇使用的博客,收到了不少宝贵意见,后来又懒得去改进,所以也没有新的文章。最近,由于学校宿舍也装校园网了,不再是用Dr.Com,我满怀心喜地试用了Srun3000,结果发现会出现连接上就一两秒掉网现象,并且提示说我的网络出现问题,与服务器连接断开,怒了!我试过各种办法,当然不包括换系统(我用的Win7),还是不行,网卡驱动也都是正常的。于是我试着用抓了次HTTP包,发现了问题所在。

  原来,srun3000会在发送了连接的包后,又自动发了个注销的包,所以导致我网络中断,并且它在提示错误后就马上自动退出了,导致我产生了程序产生致命错误的假象……好吧,先上个图,看下srun3000的“罪证”:

  先后发的两条数据,第一条便是登录,第二条便是注销(为什么会自动注销,我用ollydbg跟进看了一会,由于汇编太难看了,而且我又比较懒,所以没分析出来),这导致了我网络的中断。为了验证我的想法,我使用Fiddler手动把登录的包重发了一次,果然能正常上网了,而且到第二天都没有掉过。所以大家可以看到我这篇文章,同样使用客户端的方式,基于HTTP协议来开发一个代替Srun3000的软件。

  1、功能:连接、注销、程序开机启动、自动登录、记住密码、连接后自动最小化

  2、界面:WPF窗口、通知栏图标、软件功能设置、异步连接断开

  3、效果:

  4、基本原理:

  从抓到的数据来看,连接和断开都使用的是POST,只需要根据它的格式依照Post数据过去就可以实现连接和断开。

  连接:

POST http://172.30.16.53/cgi-bin/srun_portal HTTP/1.1Content-Type: application/x-www-form-urlencodedUser-Agent: my sessionHost: 172.30.16.53Content-Length: 138Pragma: no-cacheaction=login&username=******&password=******&drop=0&type=2&n=23&ip=0&mbytes=0&minutes=0&ac_id=3&mac=**:**:**:**:**:**&nas_ip=172.30.12.244

  断开:

POST http://172.30.16.53/cgi-bin/srun_portal HTTP/1.1Content-Type: application/x-www-form-urlencodedUser-Agent: my sessionHost: 172.30.16.53Content-Length: 87Pragma: no-cacheaction=logout&ac_id=3&username=******&mac=**:**:**:**:**:**&type=2&nas_ip=172.30.12.244

  为了安全起见,我把上面的username、password、mac三个字段的值都用“*”号代替了。

  5、核心代码

  现在我在C#客户端只需要分别使用HttpWebRequest仿照进行请求就行了,我贴上连接的核心代码:

连接核心代码
1         private Func
ConnectDelegate = Connect; // 连接委托 2 // 连接执行函数 3 private string Connect() 4 { 5 try 6 { 7 var settings = Properties.Settings.Default; 8 Uri uri = new Uri("http://" + settings.GateIP + settings.RelativeUri); 9 // 新建请求10 var request = HttpWebRequest.Create(uri);11 request.Method = "POST";12 request.ContentType = "application/x-www-form-urlencoded";13 // 请求体14 var body = Encoding.ASCII.GetBytes(15 "action=login&username=" + UserName +16 "&password=" + Password +17 "&drop=0&type=2&n=23&ip=0&mbytes=0&minutes=0&ac_id=3&mac=" + _MacAddress +18 "&nas_ip=" + settings.NasIP19 );20 request.ContentLength = body.Length;21 request.Timeout = 5000;22 var requestStream = request.GetRequestStream();23 requestStream.Write(body, 0, body.Length);24 requestStream.Close();25 // 发送请求并接收结果26 string responseBody;27 var response = request.GetResponse();28 var responseStream = response.GetResponseStream();29 using (StreamReader reader = new StreamReader(responseStream))30 responseBody = reader.ReadToEnd();31 if (responseBody.Contains("login_ok"))32 {33 _State = ConnectionState.Connected;34 return "连接成功!";35 }36 else if (responseBody.Contains("online_num_error"))37 {38 //var ping = new System.Net.NetworkInformation.Ping();39 //ping.Send("www.baidu.com");40 _State = ConnectionState.Connected;41 return "已经连接上,请不要重复登录!";42 }43 else if (responseBody.Contains("username_error"))44 return "帐号错误,请重新输入!";45 else if (responseBody.Contains("password_error"))46 return "密码错误,请重新输入!";47 else48 return "连接失败:" + responseBody;49 }50 catch (HttpListenerException ex)51 {52 return "HTTP请求出错,请检查网络是否正常!错误代码:" + ex.ErrorCode; 53 }54 catch (Exception ex)55 {56 return "连接失败!错误详情:" + ex.Message;57 }58 }

   基本情况就是通过POST请求获取返回体,然后根据返回体的内容判断连接状态,这些返回数据牲也是使用Fiddler抓取的,比如“login_ok”、“online_num_error”、“username_error”、“password_error”、“logout_ok”等。当然这仅仅只是数据通信的部分,还有其它与界面相关的处理就不多说了,另外断开操作与连接操作也非常相似,也就不贴了。经过我的观察,由于Srun3000并没有在线检测机制,它只是通知认证网关把相应的MAC地址放行,而且认证服务器也不管回收离线地址(需要Srun3000自己去POST logout请求),所以我也不用去ping了,也不用写心跳包了,so easy。

  接下来,我顺便贴上修改注册表使程序开机启动的代码:

开机启动
1         private void AutoStartupChanged() 2         { 3             RegistryKey HKLM = Registry.LocalMachine; 4             // 确认当前状态 5             string name = AppDomain.CurrentDomain.FriendlyName; 6             name = name.Substring(0, name.LastIndexOf('.')); 7             var run =  HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 8             bool hasValue = run.GetValue(name) != null; 9             try10             {11                 if (!hasValue && AutoStartup)                  // 添加启动12                 {13                     run = HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);14                     run.SetValue(name, AppDomain.CurrentDomain.BaseDirectory + name + ".exe");15                 }16                 else if (hasValue && !AutoStartup)             // 删除启动17                 {18                     run = HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);19                     run.DeleteValue(name);20                 }21             }22             catch (System.Exception ex)23             {24                 Message = "操作失败:" + ex.Message;25             }26         }

   主要也就是使用了SOFTWARE\Microsoft\Windows\CurrentVersion\Run下面的项来增加删除开机启动,这里不采用Windows服务来写的原因是,我想让这个软件成为“绿色”可携带的版本。

  其它也就不多说了,此软件目前为止用了一个星期,效果不错,没掉过线也。

转载请注明原址:

转载于:https://www.cnblogs.com/lekko/archive/2013/01/09/2841840.html

你可能感兴趣的文章
clj-xmemcached: memcached client for clojure
查看>>
SecureCRT日志自动记录
查看>>
磁盘 io 测试
查看>>
客户不提供开发者账号打包上传应用的处理方法
查看>>
Netfilter与FreeBSD的网络包过滤
查看>>
闲谈IPv6-现状和过渡
查看>>
我的友情链接
查看>>
Xcode3.2.6+iOS4.2無法上傳iPhone
查看>>
XMPP开发环境的搭建
查看>>
Docker 数据卷,数据卷容器详细介绍
查看>>
使用rman备份到挂载的NFS目录,提示ORA-19504-27054报错
查看>>
通过 rsync 搭建 CentOS 本地 yum 源服务器
查看>>
hadoop hive 常见问题解决持续更新
查看>>
如何做不浮躁的人
查看>>
终端服务设施方案共享(Part3)
查看>>
linux的基本指令--第三节
查看>>
设置tomcat为https访问
查看>>
我的友情链接
查看>>
oracle的触发器和应用
查看>>
Docker实践(五):Docker Compose
查看>>