当前位置:  互联网>综合
本页文章导读:
    ▪大并发服务器不得不说的技术--connect 异步      前面我们谈的大多是服务端与客户端的技术,服务器开发其实有时还会涉及到跨服务器的访问,比如腾讯的拍拍服务器需要知道登录的会员信息, 就需要访问会员服务器。 跨务器访问会涉及.........
    ▪修改tomcat默认的编码方式       默认情况下,tomcat使用的的编码方式:iso8859-1 修改tomcat下的conf/server.xml文件 找到如下代码:    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirec.........
    ▪模拟新浪微博登陆           新浪微博最近,更改了登陆加密过程,导致之前的模拟的hex_sha1加密方式失效了,recode返回状态不再是0.现在新浪微博使用的加密方式是RAS公钥加密过程。下面我们来分析一下sina微.........

[1]大并发服务器不得不说的技术--connect 异步
    来源: 互联网  发布时间: 2013-10-18

前面我们谈的大多是服务端与客户端的技术,服务器开发其实有时还会涉及到跨服务器的访问,比如腾讯的拍拍服务器需要知道登录的会员信息,

就需要访问会员服务器。

跨务器访问会涉及到很多的技术,比如访问权限控制,数据同步等,这里主要来学习一下传输层。

为了更容易理解,我们将访问端服务器称为客户端,被访问端服务器称为服务端。

客户端发起一个连接的过程:

socket_fd = socket( AF_INET,SOCK_STREAM,0 );

ret = connect( socket_fd, (sockaddr*)&addr, sizeof(addr) );

问题就出在第二步,connect 如果是同步的,如果服务端很忙,客户端就会一直阻塞在这里,最多有可能会耗上几十秒,开玩笑,不会吧,客户端也是个服务器唉,

敢情这块不就成了瓶颈吗。

我们来理清下思路:

就像你跟人家姑娘表白了,姑娘说今天不告诉你答案,明天打电话再告诉你,你是不是要一直不吃不喝在她家楼下等呢,还是回去好好休息等她电话。

够明白了么,我建议还是回家休息去吧,因为你还有很多很重要的事做呢。

同样的思路,客户端需要想办法把这个差事放进某个通知队列中。

解决这个问题就是在connect 前先要将 socket_fd 设为异步的(nonblocking):

 fcntl(socket_fd, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);

连接的时候如果暂时连不上,connect 返回-1,好家伙,人家姑娘害羞呢,但又不表示拒绝。

那行吧,在家等电话,先要把人家姑娘号码存起来吧。

在咱们这里就是将 socket_fd 放到通知队列中,以epoll 为例, 

struct epoll_event ee;

ee.events = EPOLLOUT | EPOLLET;

ee.data.fd = socket_fd;

epoll_ctl( epfd,  EPOLL_CTL_ADD, socket_fd,  &ee );

现在该干什么干什么去吧。

电话来了, 再做相应处理,应该高兴还是悲伤,表情函数预备下,免得到时大脑真空。

不同的是如果姑娘告诉你她答应你了事情就算完了,而epoll 回调告诉你有事件了你还需要确认一下:

getsockopt(socket_fd SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);

if( !error )

{

//OK

}

或者也可以使用 getsockname或getpeername,确认OK了才表示连接成功了。

作者:xiaofei_hah0000 发表于2013-3-21 12:05:48 原文链接
阅读:16 评论:0 查看评论

    
[2]修改tomcat默认的编码方式
    来源: 互联网  发布时间: 2013-10-18

默认情况下,tomcat使用的的编码方式:iso8859-1

修改tomcat下的conf/server.xml文件

找到如下代码:   
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
这段代码规定了Tomcat监听HTTP请求的端口号等信息。

可以在这里添加一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。

修改完成后:

<Connector port="8080"  protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />


作者:Orehs 发表于2013-3-22 10:26:00 原文链接
阅读:44 评论:0 查看评论

    
[3]模拟新浪微博登陆
    来源: 互联网  发布时间: 2013-10-18

    新浪微博最近,更改了登陆加密过程,导致之前的模拟的hex_sha1加密方式失效了,recode返回状态不再是0.现在新浪微博使用的加密方式是RAS公钥加密过程。下面我们来分析一下sina微博的加密过程。新浪微博的登陆过程和别的网站不同之处就只是他对密码的加密过程有点繁琐,只要我们分析密码加密过程,问题就能解决。

    首先,用firefox浏览器开启firebug,打开新浪微博登陆首页,在网络状态下找到  http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.5)&_=1363935021054, 这条链接里面携带重要的信息,servertime,nonce,pubkey这些参数都是加密的重要信息。

sinaSSOController.preloginCallBack(
{"retcode":0,
"servertime":1363935070,
"pcid":"gz-454de2caeb7e34b78681bbfddb4b25da343c",
"nonce":"9Z70SO",
"pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","exectime":1})

其中pubkey就是现在新浪微博的加密公钥。再找到 http://tjs.sjs.sinajs.cn/t5/register/js/page/login/index.js?version=201303221451 下载这条登陆js,我们在js中可以找到这段代码 

          if (a.loginType & z && a.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) {
                e.servertime = a.servertime;
                e.nonce = a.nonce;
                e.pwencode = "rsa2";
                e.rsakv = a.rsakv;
                var f = new sinaSSOEncoder.RSAKey;
                f.setPublic(a.rsaPubkey, "10001");
                c = f.encrypt([a.servertime, a.nonce].join("\t") + "\n" + c)
            } else if (a.loginType & A && a.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) {
                e.servertime = a.servertime;
                e.nonce = a.nonce;
                e.pwencode = "wsse";
                c = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(c)) + a.servertime + a.nonce)
            }

  以前的满足条件的加密过程是:
  c = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(c)) + a.servertime + a.nonce)
执行这句代码的加密方式有前辈已经贴出

http://blog.csdn.net/wolfphantasms/article/details/7398260(hex_sha1 ,三次hex_sha1加密过程)

而现在使用的加密过程是:

 c = f.encrypt([a.servertime, a.nonce].join("\t") + "\n" + c)

因此只要在登陆js中提炼出RSA的加密函数就ok了。只要在java中调用js代码来加密登陆密码,至于servertime,nonce都可以自己模拟生成。下面是我产生servertime,nonce、和加密密码的方法:

private String encodeAccount(String account) {
        String userName = "";
        try {
            userName = Base64.encodeBase64String(URLEncoder.encode(account,
                    "UTF-8").getBytes());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return userName;
    }    
public String makeNonce(int len) {
		String x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String str = "";
		for (int i = 0; i < len; i++) {
			str += x.charAt((int) (Math.ceil(Math.random() * 1000000) % x
					.length()));
		}
		return str;
	}

	public String RSAencode(String publickey, String servertime,
			String nonce, String pw) {
		ScriptEngineManager manager = new ScriptEngineManager();

		ScriptEngine engine = manager.getEngineByName("javascript");

		String root = System.getProperty("user.dir");
		logger.debug(root);
		/*
		 * 指定加密RSA加密文件
		 */
		String jsFileName = root + "/src/main/js/sinaRSA.js";
		/*
		 * 读取js文件
		 */
		FileReader reader;
		String pass = "";
		try {
			reader = new FileReader(jsFileName);

			engine.eval(reader);

			if (engine instanceof Invocable) {
				Invocable invoke = (Invocable) engine;
				// 调用encrypt方法,并传入密码加密
				pass = invoke.invokeFunction("sinaRsa", publickey.trim(),
						servertime.trim(), nonce.trim(), pw.trim()).toString();
				logger.debug("after encode password = : " + pass);
				return pass;

			}
			reader.close();
		} catch (Exception e) {
			logger.error("js load fail .... ", e);
		}
		return pass;
	}

	private String getServerTime() {
		long servertime = new Date().getTime() / 1000;
		return String.valueOf(servertime);
	}

登陆js如下:

function sinaRsa(pbkey, servertime, nonce, pw) {
	var f = new sinaSSOEncoder.RSAKey;
	f.setPublic(pbkey, "10001");
	var psw = f.encrypt([servertime, nonce].join("\t") + "\n" + pw);
	return psw;
}
var sinaSSOEncoder = sinaSSOEncoder || {};
(function() {
	
	var a = 0, b = 8;
	this.hex_sha1 = function(a) {
		return i(c(h(a), a.length * b))
	};
	var c = function(a, b) {
		a[b >> 5] |= 128 << 24 - b % 32;
		a[(b + 64 >> 9 << 4) + 15] = b;
		var c = Array(80), h = 1732584193, i = -271733879, j = -1732584194, k = 271733878, l = -1009589776;
		for (var m = 0; m < a.length; m += 16) {
			var n = h, o = i, p = j, q = k, r = l;
			for (var s = 0; s < 80; s++) {
				s < 16 ? c[s] = a[m + s] : c[s] = g(c[s - 3] ^ c[s - 8] ^ c[s - 14] ^ c[s - 16], 1);
				var t = f(f(g(h, 5), d(s, i, j, k)), f(f(l, c[s]), e(s)));
				l = k;
				k = j;
				j = g(i, 30);
				i = h;
				h = t
			}
			h = f(h, n);
			i = f(i, o);
			j = f(j, p);
			k = f(k, q);
			l = f(l, r)
		}
		return [h, i, j, k, l]
	}, d = function(a, b, c, d) {
		return a < 20 ? b & c | ~b & d : a < 40 ? b ^ c ^ d : a < 60 ? b & c | b & d | c & d : b ^ c ^ d
	}, e = function(a) {
		return a < 20 ? 1518500249 : a < 40 ? 1859775393 : a < 60 ? -1894007588 : -899497514
	}, f = function(a, b) {
		var c = (a & 65535) + (b & 65535), d = (a >> 16) + (b >> 16) + (c >> 16);
		return d << 16 | c & 65535
	}, g = function(a, b) {
		return a << b | a >>> 32 - b
	}, h = function(a) {
		var c = [], d = (1 << b) - 1;
		for (var e = 0; e < a.length * b; e += b)
			c[e >> 5] |= (a.charCodeAt(e / b) & d) << 24 - e % 32;
		return c
	}, i = function(b) {
		var c = a ? "0123456789ABCDEF" : "0123456789abcdef", d = "";
		for (var e = 0; e < b.length * 4; e++)
			d += c.charAt(b[e >> 2] >> (3 - e % 4) * 8 + 4 & 15) + c.charAt(b[e >> 2] >> (3 - e % 4) * 8 & 15);
		return d
	};
	this.base64 = {
		encode : function(a) {
			a = "" + a;
			if (a == "")
				return "";
			var b = "", c, d, e = "", f, g, h, i = "", j = 0;
			do {
				c = a.charCodeAt(j++);
				d = a.charCodeAt(j++);
				e = a.charCodeAt(j++);
				f = c >> 2;
				g = (c & 3) << 4 | d >> 4;
				h = (d & 15) << 2 | e >> 6;
				i = e & 63;
				isNaN(d) ? h = i = 64 : isNaN(e) && ( i = 64);
				b = b + this._keys.charAt(f) + this._keys.charAt(g) + this._keys.charAt(h) + this._keys.charAt(i);
				c = d = e = "";
				f = g = h = i = ""
			} while(j<a.length);
			return b
		},
		_keys : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
	}
}).call(sinaSSOEncoder);
(function() {
	function bt(a) {
		var b = bp(a, this.n.bitLength() + 7 >> 3);
		if (b == null)
			return null;
		var c = this.doPublic(b);
		if (c == null)
			return null;
		var d = c.toString(16);
		return (d.length & 1) == 0 ? d : "0" + d
	}
	function bs(a) {
		return a.modPowInt(this.e, this.n)
	}
	function br(a, b) {
		if (a != null && b != null && a.length > 0 && b.length > 0) {
			this.n = bm(a, 16);
			this.e = parseInt(b, 16)
		} else
			alert("Invalid RSA public key")
	}

	function bq() {
		this.n = null;
		this.e = 0;
		this.d = null;
		this.p = null;
		this.q = null;
		this.dmp1 = null;
		this.dmq1 = null;
		this.coeff = null
	}

	function bp(a, b) {
		if (b < a.length + 11) {
			alert("Message too long for RSA");
			return null
		}
		var c = [], e = a.length - 1;
		while (e >= 0 && b > 0) {
			var f = a.charCodeAt(e--);
			if (f < 128)
				c[--b] = f;
			else if (f > 127 && f < 2048) {
				c[--b] = f & 63 | 128;
				c[--b] = f >> 6 | 192
			} else {
				c[--b] = f & 63 | 128;
				c[--b] = f >> 6 & 63 | 128;
				c[--b] = f >> 12 | 224
			}
		}
		c[--b] = 0;
		var g = new bl, h = [];
		while (b > 2) {
			h[0] = 0;
			while (h[0] == 0)
			g.nextBytes(h);
			c[--b] = h[0]
		}
		c[--b] = 2;
		c[--b] = 0;
		return new d(c)
	}

	function bo(a) {
		return a < 16 ? "0" + a.toString(16) : a.toString(16)
	}

	function bn(a, b) {
		var c = "      
    
最新技术文章:
▪用户及权限基础 2---- Linux权限    ▪用户及权限基础 3---- Linux扩展权限    ▪git 简明教程(1) --创建及提交
▪背包 代码    ▪json对象的封装与解析    ▪01背包,完全背包,多重背包 ,模板代码
▪apache安装详解    ▪HDU 4668 Finding string (解析字符串 + KMP)    ▪《TCP-IP详解 卷1:协议》学习笔记(二)
▪《TCP-IP详解 卷1:协议》学习笔记(持续更新...    ▪windows下使用swig    ▪gensim试用
▪Linux Shell脚本编程--nc命令使用详解    ▪solr对跨服务器表联合查询的配置    ▪递归和非递归实现链表反转
▪Linux磁盘及文件系统管理 1---- 磁盘基本概念    ▪Cholesky Decomposition    ▪HTTP协议学习
▪用C语言写CGI入门教程    ▪用hdfs存储海量的视频数据的设计思路    ▪java多线程下载的实现示例
▪【原创】eAccelerator 一个锁bug问题跟踪    ▪hadoop学习之ZooKeeper    ▪使用cuzysdk web API 实现购物导航类网站
▪二维数组中的最长递减子序列    ▪内嵌W5100的网络模块WIZ812MJ--数据手册    ▪xss 跨站脚本攻击
▪RobotFramework+Selenium2环境搭建与入门实例    ▪什么是API    ▪用PersonalRank实现基于图的推荐算法
▪Logtype    ▪关于端口号你知道多少!    ▪Linux基本操作 1-----命令行BASH的基本操作
▪CI8.7--硬币组合问题    ▪Ruby on Rails 学习(五)    ▪如何使用W5300实现ADSL连接(二)
▪不允许启动新事务,因为有其他线程正在该会...    ▪getting start with storm 翻译 第六章 part-3    ▪递归求排列和组合(无重复和有重复)
▪工具类之二:RegexpUtils    ▪Coding Interview 8.2    ▪Coding Interview 8.5
▪素因子分解 Prime factorization    ▪C# DllImport的用法    ▪图的相关算法
▪Softmax算法:逻辑回归的扩展    ▪最小生成树---Kruskal算法---挑战程序设计竞赛...    ▪J2EE struts2 登录验证
▪任意两点间的最短路径---floyd_warshall算法    ▪Sqoop实现关系型数据库到hive的数据传输    ▪FFMPEG采集摄像头数据并切片为iPhone的HTTP Stream...
▪Ubuntu 13.04 – Install Jetty 9    ▪TCP/IP笔记之多播与广播    ▪keytool+tomcat配置HTTPS双向证书认证
▪安装phantomjs    ▪Page Redirect Speed Test    ▪windows media player 中播放pls的方法
▪sre_constants.error: unbalanced parenthesis    ▪http headers    ▪Google MapReduce中文版
▪The TCP three-way handshake (connect)/four wave (closed)    ▪网站反爬虫    ▪Log4j实现对Java日志的配置全攻略
▪Bit Map解析    ▪Notepad 快捷键 大全    ▪Eclipse 快捷键技巧 + 重构
▪win7 打开防火墙端口    ▪Linux Shell脚本入门--awk命令详解    ▪Linux Shell脚本入门--Uniq命令
▪Linux(Android NDK)如何避免僵死进程    ▪http Content-Type一览表    ▪Redis实战之征服 Redis + Jedis + Spring (二)
▪Tomcat7.0.40 基于DataSourceRealm的和JDBCRealm的资源...    ▪利用SQOOP将ORACLE到HDFS    ▪django输出 hello world
▪python re    ▪unity3D与网页的交互    ▪内存共享基本演示
▪python join    ▪不再为无限级树结构烦恼,且看此篇    ▪python实现变参
▪打开文件数限制功能不断地制造问题    ▪Arduino Due, Maple and Teensy3.0 的 W5200性能测试    ▪Selenium实例----12306网站测试
▪基于协同过滤的推荐引擎    ▪C4.5决策树    ▪C#HTTP代理的实现之注册表实现
▪nosql和关系型数据库比较?    ▪如何快速比较这两个字符串是否相等?    ▪hdoj 1863 畅通工程 最小生成树---prime算法
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3