一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Programming Language

注意DotNet的ConnectionLimit

由于不熟悉C#的开发,在做一个系统WS接口的压力测试时走了弯路。发现这个问题的原委是要在用C#压力测试我们的一个REST Web Service.服务器上我理论预计的性能是100并发,4s内响应完成。这个系统提供了给DotNet的客户端,使用hammock库编写而成,在压力测试中,系统性能总是上不来,在查看服务器日志后发现请求都是串行处理的,所以维持了400ms每个请求的性能水平,而理论上的十个通道的并行处理的性能没有达到。我开始以为是否是同事编写的客户端有问题,检查之后发现没有任何问题;转而寻求是否是Hammock库的问题,未果。然后怀疑服务器的问题,我使用Java,restclient库编写了一个测试程序,发现10个通道全部启用,达到了理论性能,服务器方面完成不成问题。所以应该是C#方面的问题,Hammock的源码比较复杂,看了半天也没啥发现,在我们的这个RestClient中有点杀鸡用牛刀的感觉,是否是其中的什么Bug呢?所以准备自行编写客户端。由于服务器上使用Rest,XML传输格式的XSD文件也已经生成,客户端上都是使用xsd文件反向生成的POCO对象,查了一下C#的文档,直接使用XmlSerializer就可以很方便的实现序列化和反序列化了。并且System.Net命名空间中有HttpWebRequest类,很容易自行实现自己的客户端,而不是用hammock库,这样就可以排除hammock的问题。昨晚自己写了一下,一测试性能还是无法达到,使用netstat查看连接,居然发现同时还只有两个连接到服务器。觉得奇怪,所以使用C# Socket Connection limit之类的关键字Google,原来C#类库中,HttpWebRequest默认的最大连接数为2,为什么是个二呢?想不通,其实我觉得既然作为类库,C#完全不必要限制客户端的连接数,这是由程序员控制的啊。有两个办法设置不同的连接数。 1. HttpWebRequest.ServicePoint.ConnectionLimit 2. ServicePointManager.DefaultConnectionLimit 任意设置一个到我的最大并行处理数,比如时,性能马上就上去了,几乎逼近于理论性能,但是相比使用Java测试的结果还是要整体慢3s左右,因为不知道什么原因,在首次连接服务器时,会有一个几秒的延迟。不知道具体原因是什么,是否又有什么默认设置?又经过了一番搜索和研究,终于发现了真正的原因,在使用HttpWebRequest类的时候,默认会去检查代理服务器设置,这样当然就慢了。而且可以在app.config中设置连接数和代理服务器的设置,而不需要在程序中硬编码了。  <system.net>    <defaultProxy enabled="false">      <proxy/>      <bypasslist/>      <module/>    </defaultProxy>    <connectionManagement>      <add address="*" maxconnection="10"/>    </connectionManagement>  </system.net> PS:最近用Visual Studio,用C#,不知道仍然是先入为主的习惯问题,总觉得没有使用Eclipse编写Java好用,首先是自己对代码编写的快捷键不熟悉,所以效率要慢一半 为什么不能用源码绑定到dll上,就像在eclipse里把src绑定到jar包上一样 为什么就没有一个快捷键全部快速自动导入命名空间呢 为什么就没有一个Ctrl+O,快速定位到类或者资源呢,不要跟我说Ctrl+,,把方法,类,字段啥都混在一起了 最后经过了一番搜索,发现了有个Visual Studio的插件,Productive PowerTools,可以增强有些特性,比如使用Alt+Up上移一行代码,Alt+Down下移当前行代码,这跟在Eclipse中的操作习惯一致了,不过这并没有自动把移动的代码格式化,这是Eclipse要强大的地方。   光子:经测试,config的配置项是可用的。   from:http://blog.sina.com.cn/s/blog_3eea4f680100s48d.html

龙生   28 Apr 2018
View Details

数据抓取 C# 基础连接已经关闭: 发送时发生错误。

光子:此方法我未测试,用上篇文章中的方法解决了,有兴趣的小伙伴试一下。 4-28 测试了一下,对我的程序没用。 在程序中获取某个https网址的源码,GetRespose()时 出现了“基础连接已经关闭: 发送时发生错误。”的错误提示。 翻了论坛后,有个仁兄说:                 //.net 4.0 设置: ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;                 //.net 4.5 设置: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls1.2; 我看了眼自己写的程序,是.net4.0的 于是写了上边这句,就好了。 原因虽然没搞清楚。但体会很深。懂行的就是一句话。不懂行的折腾几天,胡咧咧,没用。 这句话,值多少钱? 除此之外,上午碰见了关于安全性提示的问题,相关的话分别是 //ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 谁知道有没有用呢,记下来,有用没用以后再说。 from:http://blog.163.com/g3631417@126/blog/static/3666747620178523250968/

龙生   27 Apr 2018
View Details

C#模拟Http请求时出现 基础连接已经关闭 未能为 SSLTLS 安全通道建立信任关系

光子:亲测可用。我原来的代码写的是:ServicePointManager.ServerCertificateValidationCallback=RemoteCertificateValidate; 唯独少了个+号,…………………………%……&%%¥#¥¥¥%¥%……………… 光子:2018/04/27/13:56 又出现了,有点效果。 from:https://www.cnblogs.com/ianunspace/p/5508179.html

龙生   27 Apr 2018
View Details

c#中 HttpWebRequest请求抛异常,基础连接已经关闭: 连接被意外关闭

在用httpWebRequest模拟请求的时候有时因为服务器等方面做了请求的限制, 在请求会出现基础连接已经关闭: 接收时发生意外错误的错误 一般原因是因为服务器不允许与 Internet 资源建立持久性连接连接和http的版本造成 做如下简单修改httpWebRequest即可解决   1 2 request.KeepAlive = false;  //设置不建立持久性连接连接 request.ProtocolVersion = HttpVersion.Version10; //http的版本有2个,一个是1.0,一个是1.1 具体更具实际情况测试替换 from:https://www.cnblogs.com/yunspider/p/5020103.html

龙生   26 Apr 2018
View Details

[C#]如何获取变量的名字,不是值,是名称。返回名字的字符串

找了好久,最后在国外的论坛找到了解决办法,直接贴代码吧。 方法一:

方法二:

from:https://www.cnblogs.com/huangcong/p/3459307.html

龙生   26 Apr 2018
View Details

c# WebBrowser获取cookie

from:https://www.cnblogs.com/zhangzhu/p/3408317.html

龙生   25 Apr 2018
View Details

C#使用Thread.Sleep()导致程序无响应的解决办法

有时候我们在编写C#程序时需要某个线程睡眠一段时间,一般情况下,我们首先会想到用Thread.Sleep()方法,但是有时候用这个方法的时候会导致程序出现无响应的状况,那有没有其他办法来替代这个方法呢?答案是肯定的,下面亦是美网络就给大家介绍一下Thread.CurrentThread.Join()方法。 首先我们来看一下msdn帮助文档是如何介绍的: Thread.Sleep(); //将当前线程挂起指定的时间。 Thread.CurrentThread.Join(); //在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。 如果仅仅从字面上理解的话,Thread.Sleep();只是将线程挂起,即使当前线程没终止,还可以继续被调用。而Thread.CurrentThread.Join()方法不仅阻塞调用线程,并且还必须等到该线程终止。 这样的话,使用Thread.Sleep();有时就会导致程序出现无响应的情况,而使用Thread.CurrentThread.Join()程序将不会出现无响应,但是其他操作需要等待当前线程终止才会继续。 PS:要使用Thread类,需调用using System.Threading;命名空间。   from:http://www.yishimei.cn/network/390.html

龙生   25 Apr 2018
View Details

C# WebRequest使用代理进行HTTP协议的GET和POST调用

System.Net.WebRequest类,是通过HTTP协议与Web服务器进行交互的实现。 开发工具:VS2012,控制台应用程序 以下通过实例代码进行讲解,先不使用代理进行GET和POST调用;然后通过指定代理、本地IE代理进行GET和POST调用,循序渐进的学习。 GET和POST调用实现类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 […]

龙生   25 Apr 2018
View Details

C#,往线程里传参数的方法总结

Thread (ParameterizedThreadStart) 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。 Thread (ThreadStart) 初始化 Thread 类的新实例。 由 .NET Compact Framework 支持。 Thread (ParameterizedThreadStart, Int32) 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托,并指定线程的最大堆栈大小。 Thread (ThreadStart, Int32) 初始化 Thread 类的新实例,指定线程的最大堆栈大小。 由 .NET Compact Framework 支持。 我们如果定义不带参数的线程,可以用ThreadStart,带一个参数的用ParameterizedThreadStart。带多个参数的用另外的方法,下面逐一讲述。 一、不带参数的   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System;  using System.Collections.Generic;  using System.Text;  using System.Threading;  namespace AAAAAA  {    class AAA    {    public static void Main()    {    Thread t = new Thread(new ThreadStart(A));    t.Start();    Console.Read();    }    private static void A()    {    Console.WriteLine("Method A!");    }    }  } 结果显示Method A! 二、带一个参数的 由于ParameterizedThreadStart要求参数类型必须为object,所以定义的方法B形参类型必须为object。   1 […]

龙生   25 Apr 2018
View Details

构造HTTP请求Header实现“伪造来源IP”

在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信。这就像我们给对方写信时,如果写出错误的发信人地址,而收信人按信封上的发信人地址回信时,原发信人是无法收到回信的。 一些DDoS 攻击,如 SYN flood,  就是利用了 TCP/ip 的此缺陷而实现攻击的。《计算机网络》教材一书上,对这种行为定义为“发射出去就不管”。 因此,本文标题中的伪造来源IP 是带引号的。并非是所有 HTTP 应用程序中存在此漏洞。 那么在HTTP 中, " 伪造来源 IP",  又是如何造成的?如何防御之? 在理解这个原理之前,读者有必要对HTTP 协议有所了解。 HTTP 是一个应用层协议,基于请求 / 响应模型。客户端(往往是浏览器)请求与服务器端响应一一对应。 请求信息由请求头和请求正文构成(在GET 请求时,可视请求正文为空)。请求头类似我们写信时信封上的基本信息,对于描述本次请求的一些双方约定。而请求正文就类似于信件的正文。服务器的响应格式,也是类似的,由响应头信息和响应正文构成。 为了解这个原理,可使用Firefox Firebug,  或 IE 浏览器插件 HTTPwatch 来跟踪 HTTP 请求 / 响应数据。 本文中,以HTTPwatch 为例说明之。安装 httpwatch 并重启 IE 浏览器后, IE 的工具栏上出现其图标,点击并运行 Httpwatch,  就会在浏览器下方显示出 HTTPWatch 的主界面。 点击左下角红色的“Record ”按钮,并在地址栏输入 www.baidu.com,  等页面打开后,选中一个请求,并在下方的 tab 按钮中选择“ Stream ”,如图: 左边即是请求数据,右边即是服务器响应数据。左边的请求头均以回车换行结束,即“\r\n ” ,  最后是一个空行(内容为 \r\n ) , 表示请求 header 结束。而请求 header 中除第一行外,其它行均由 header 名称, header 值组成,如  Accept-Encoding: gzip, deflate , header 名称与值之间有冒号相隔,之间的空格是可有可无的。 那么,在HTTP 应用程序中,如何取得指定的请求 header 信息呢?这里使用 PHP 语言为例说明。对所有客户端请求 header, PHP 程序中取得其值的方式如下: $_SERVER['HTTP_ HEADER_NAME '] HEADER_NAME应该以换成对应的 header 名称,此项的规律是:全大写,连接线变成下划线。比如要取得客户端的User-Agent 请求头,则使用 $_SERVER['HTTP_USER_AGENT'],  掌握这个规律,即可达到举一反三的效果。如要取得 COOKIE 信息,则使用 $_SERVER['HTTP_COOKIE'] 即可。也就是说, $_SERVER 数组中,以 HTTP 开头的项均属于客户端发出的信息。 回归到HTTP 应用程序层,来源 IP 的重要性不言而语,例如表单提交限制,频率等等均需要客户端 IP 信息。使用流行的 Discuz X2.5  的文件 source/class/discuz/discuz_application.php 中的代码片断: private function _get_client_ip() { $ip = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; 如以下的JSP代码片段: public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } 以上代码片段即是获取客户端IP ,这段程序会尝试检查 HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR,  根据之前的原理说明,以 HTTP_ 开头的 header,  均属于客户端发送的内容。那么,如果客户端伪造 Client-Ip, X-Forward-For ,不就可以欺骗此程序,达到“伪造 IP ”之目的? 那么如何伪造这项值?如果你会写程序,并了解HTTP 协议,直接伪造请求 header 即可。或者使用 Firefox 的Moify Headers 插件即可。 按图示顺序号输入或点击相应按钮。Start 按钮这里变为红色 Stop ,说明设置成功。 这时,如果我们使用Firefox 访问其它网站,网站服务器就针接收到我们伪造的 X-Forward-For,  值为 1.1.1.1 。 严格意义上讲,这并不是程序中的漏洞。Discuz 为了保持较好的环境兼容性 ( 包含有反向代理的 web 服务器环境,如 nginx 作为 php fastcgi 的前端代理 ) ,如此处理是可以理解的。那么如何处理,才能杜绝这个问题呢? 服务器重新配置X-Forward-For 为正确的值。 如对典型的nginx + php fastcgi 环境( nginx 与 php fastcgi 是否位于同一机器,并不妨碍此问题的产生) , nginx和 php fastcig 进程直接通信: 切记,$_SERVER['REMOTE_ADDR']  是由 nginx 传递给 php 的参数,就代表了与当前 nginx 直接通信的客户端的 IP (是不能伪造的)。 再比如,存在中间层代理服务器的环境: 这种情况下,后端的HTTP 文件服务器上获取取的 REMOTE_ADDR 永远是前端的 squid/varnish cache 服务器的通信 IP 。 服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定X-Forward-For 的值,后端所有机器不作任何设置,直接信任并使用前端机器传递过来的 X-Forward-For 值即可。 即在最前端的Nginx 上设置: location  ~  ^/static { proxy_pass  ….; proxy_set_header X-Forward-For $remote_addr ; […]

龙生   20 Apr 2018
View Details
1 93 94 95 178