iseopad-SEO技术,SEO文章,SEO学习 SEO技术学习交流园地

四月 4, 2016

C#使用Dotfuscator混淆代码的加密方法

Filed under: C# — 标签: — iseopad @ 5:35 下午

C#编写的代码如果不进行一定程度的混淆和加密,那么是非常容易被反编译进行破解的,特别是对于一些商业用途的C#软件来说,因为盯着的人多,更是极易被攻破。使用Dotfuscator可以实现混淆代码、变量名修改、字符串加密等功能。

这里介绍的是DotfuscatorPro_4.9.7750_2.0 版本,有需要的可以到网上搜索下载https://skydrive.live.com/?cid=d2b11227abf128d8&id=D2B11227ABF128D8%21104。安装 Dotfuscator 好 打开界面,有几个需要配置的地方: Options、Input、Rename、String Encryption、Build,其他的默认即可,下面一一讲解。

 

 

Settings->Global Options 这是全局配置选项:

把 Disable String Encryption 设为 NO,即启用字符串加密;检查 Disable Control flow、Dsiable Renaming 也为 NO,即保证控制流和混淆功能打开,其他默认。如下图:

 

Input 选项里 选择你需要混淆加密的 dll、exe文件,其中Library不要勾选,否则有些类、变量等等不会混淆;

 

Rename 选项 勾选“use enhanced overload induction”(使用增强模式),注意:不要勾选下方的“ Do not suppress on serializable types”,即序列化类型的变量不加密,否则编译后可能异常; “Renaming Scheme” 选择“Unprintable”(不可打印字符,即乱码),也可以选择其他如小写字母、大写字符、数字的方式。如下图:

 

String Encryption 选项 include里勾选需要字符串加密的工程文件exe、dll等。

 

Settings->Build Settings 选项 设置输出目标文件夹,点击上方的按钮即可重新生成新的 exe、dll文件了。

 

好了,我们来看一下加密混淆后的效果:

 

原来的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
//const int A = B * 10;
//const int B = 10;

public static void Main(string[] args)
{
Person p = new Person();            
Console.WriteLine(“A is {0},B is {1} “, A, B);
}
}

public class Person
{
static int age;
}

}

经过Dotfuscator混淆加密后,我们使用著名的反编译软件 Reflector 来查看,可以发现函数体内的代码已经看不到了,字符串也变成了乱码,函数名称也不可见了,效果图如下:

 

使用Dotfuscator混淆的几个注意点】:
1、如果你加密的dll、exe里有public类,需要被外部引用的话,那么引用这个public的相关dll、exe也要一起放到Dotfuscator Input 里,同时进行混淆加密,不然外部调用出错。
2、如果有public类,但是你不想照着第1点的方式做的话,可以勾选 Library 模式(input 里 展开项目,见下图),或者不选择 rename 选项,仅仅用 control flow 混淆(该种方式下会看见类名、函数名,但是看不到函数体)。

C#使用Dotfuscator混淆代码的加密方法

3、如果有public类,但是你也不想按照我的第一点、第二点的方法做的话,可以在rename选项里排除这些public的类名、方法名、属性名即可:使用 rename exclude 里左侧排除项目,或 右侧 正则排除方法,见下图:

C#使用Dotfuscator混淆代码的加密方法

当然,软件世界没有不能破解的,但是利用Dotfuscator混淆加密后 至少可以挡住不少新手们!

四月 3, 2016

SEO利器-Google GSA虚拟机版本

Filed under: Google,SEO技术 — iseopad @ 6:59 下午

SEO利器-Google GSA虚拟机版本

在所有的SEO工具中,能够被称为利器的工具不多,但Google GSA虚拟机版本绝对算是一个。去年我介绍了《利用Google Search Appliance 服务器做SEO 》,不过这个正式版实在太昂贵而且根据美国的某条法律不销售给中国,所以很多人都没办法用来做SEO应用。 而Google GSA虚拟机版本就很好的解决了这个问题。

GSA

GSA

先讲讲这个Google GSA虚拟机版本怎么应用到SEO上面吧。

如我以前所说:

你可以把这个GSA看做是google 的微缩版,它有爬虫,有索引库,有排序算法。它的的硬件和软件都是现在google.com这个网站正在用的东西。所以两者之间相似程度非常的高。我在过去操作google mini的时候已经证实:至少它的抓取机制和现在的google.com几乎是一摸一样的。

其实何止爬虫抓取机制,连绝大部分排序的算法都是一样的。虽然这个GSA内置了更多给离线文档(如 pdf\word\)排序的算法,但是在给网页排序这块的算法和google.com如今正在用的算法是非常接近的。因为这个GSA的本意是给某些需要搜索的企业用户来索引他们自己的信息,是希望用google的技术能力来帮他们索引最相关的信息,不然就没有必要非得用google的产品了。 开发过小规模搜索引擎的人都知道,对于小型搜索引擎,其他东西大家都能基本做到,GSA值钱的地方就是这个排序算法,这是大家选择GSA的首要原因。

另外,这个方法是一个有着11年SEO经验并且在美国google做过2年产品经理的人强烈推荐使用的方法,他自己就买了2台正式版。

不过排序算法总还是有差别的,根据我使用了2年多GSA的经验,对于网页的排序算法90%以上是一样。

GSA在SEO方面至少有以下几个应用。

第一个应用就是检查搜索引擎爬虫在你网站上可能遇到的问题。

因为这是一个真正的搜索引擎,而且对于google来说,GSA和google.com的爬虫是一模一样的,所以检查到的问题都是真正的搜索引擎爬虫会遇到的问题。

操作方法为:

点击“抓取并编制索引”—>  “抓取网址”,按如下格式输入你要检查的网址,按后点击“保存要抓取的网址”。

设置待抓取URL

设置待抓取URL

在“状态和报告”—>“ 抓取状态”里,点击“恢复抓取”。

等一段时间以后,如果一切正常,在GSA的前台就可以开始搜索到网站的内容。

在“状态和报告”—>“抓取状态”里,就可以看到爬虫遇到的一些问题。如:

检索错误

检索错误

点击出错的部分,会列出哪些URL因为什么原因出错。

出错的URL

出错的URL

这个虚拟机版本已经内置了一些数据。每次测试前,都需要把数据清空。 在“管理”—>“重置索引”里, 点击“立即重置索引”可以清空所有已经抓取的数据。

看着这些似曾相识的界面,应该能明白我以前写那篇《google 的良苦用心:网站管理员工具》的依据了。

第二个应用就是可以探测到google大部分基本的排序规则。

以前很多人在做SEO过程中对很多排名因素都是不能确定的。 如:到底 h1 放多少个好、有没有必要加导出链接等等。

有了GSA,就可以做大量的 A/B测试,就能把很多因素都测试出来。 如:测试<h2>  和 <strong> 这两个标签哪个对排名的影响更大一点。

那就可以设计A和B两个网页,其他部分都一模一样,只是某个特定的关键词,A网页是用 <h2> 加粗的,B网页是用 <strong> 加粗的。 用GSA只收录这两个网页,并且只对这两个网页进行排名。在前台搜索这个关键词,看哪个网页排在前面,这样就可以知道哪个因素对排名的影响大一些了。

有点需要注意一下的是,那些被测试的网页,如果上面有链接而你又没做限制的话,爬虫会顺着这些链接把很多网页都收录进来,那会对测试结果造成干扰。

A/B测试

A/B测试

类似的测试方法还有很多,只要你想得到都可以去测试。 这样能把google宣称的200多项排序规则中的一大半规则都可以测试出来。 不过要明白一点的是:即使能把所有的规则测试出来,也不一定能做好SEO,在《怎样形成一套非常科学系统的SEO方法》中我说过:做搜索引擎是一回事,在搜索引擎上拉流量又是另一回事。 等大家把很多排序规则都测试出来了再来做SEO就明白了。

只是知道了这些规则,那就不需要听那些毫无来由的SEO规则了,很多事情你自己完全能确定是怎么回事。还有就是就算要向你老板交代你的SEO做法的时候也可以理直气壮一点。

另外,由于百度也在不停的“学习”google的算法,所以这里的很多规则对百度也适用。(其实大部分搜索引擎的很多做法,甚至开发语言都是一模一样的。 顺便广告一下: 杭州光年已经能开发搜索引擎及其很多应用。如小型搜索引擎、网站站内搜索、基于搜索的舆情监控系统、公司内部文档搜索等等。不是用开源程序开发。)

第三个应用就是可以查看内部链接的结构,看哪些网页被内部链接推荐得多一点。

在《内部链接还是外部链接?》一文中,讲述了内部链接的重要性。 但是极少有网站知道自己的每个网页内部链接的分布情况,有了GSA,这个就很容易办到了。

在“状态和报告”—>“ 抓取状态”里,输入刚才GSA收录的网址,“网址状态”选 “已抓取”,就可以查询到已经被收录的网页的PR在站内有多高。

站内PR分布

站内PR分布

这是在没有任何外部链接的情况下,网站纯依靠自身的内部链接造就的网站内部的PR值分布情况。 点击具体的URL,还可以查看详细的信息如:

每个URL的信息

每个URL的信息

当然还有其他一些应用,如:只收录自己的网页和竞争对手的网页并进行排序,如果你自己的网页排在后面,就不停的改进直到超过对手的网页。其他更多的应用还是靠大家慢慢发掘吧,都写出来就没什么意思了。用它确实是可以做出一个完美的SEO网页。

这个虚拟机版本是运行在Vmware上的,Vmware7.1.3 的下载地址是:http://download.pchome.net/system/sysenhance/redirectsrv-4673-1.html

初次使用虚拟机的同学最好装个Vmware7.1.3的汉化补丁。

GSA虚拟机版本的下载地址放在光年论坛上:  (需要论坛会员才能看到下载地址)

http://www.gnbase.com/thread-13-1.html

Vmware的安装过程略过,不过注意一下Vmware在安装过程中会安装几个虚拟网卡,如果电脑上的防火墙提示你的时候,一定要允许共享或通过。

要使用GSA,google官方建议的电脑配置为:

  • Intel Pentium D 处理器 915(双核)或同级别的处理器
  • 4 GB 内存
  • 40 GB 可用硬盘空间,且硬盘转速为 7200 RPM 或更快
  • SATA 或更佳存储接口

不过我在双核 1.8G 、2GB内存的笔记本上运行也不是太慢。之所以建议用40GB的硬盘空间是因为这个虚拟机版解压缩以后的大小是近35GB。

Vmware安装好以后,直接导入解压缩以后的那个vgsa.vmx ,然后打开虚拟机电源,接下来就是一段漫长的等待。

虚拟机导入

虚拟机导入

等出现配置界面的时候,就开始配置。

配置界面

配置界面

大部分情况下,都需要手动配置GSA的设置,不然在后台抓取网页的时候会出现“DNS错误”。先用 ipconfig 命令查看你本机的IP ,再来配置GSA。

按 Ctrl + G 进入虚拟机,再按 F2  ,按键盘上的 -> 选择 Manual ,IP 地址要填和你的电脑在同一个网段的其他IP地址。 其他和你本机的一样。 DNS就填和 Gateway 一样的地址,DNS Suffix 可以随便填。

配置,按TAB键换行

配置,按TAB键换行

即使配置好了,可能还不能马上使用,需要等待一会。 我记得GSA正式版从启动到能使用是需要等20分钟的,虚拟机版本也需要稍等一会。

GSA的后台访问地址是: http://{刚才配置的IP}:8000   , 前台访问地址是:http://{刚才配置的IP}。后台的登录密码压缩包里有。

软件的使用细节还有很多,GSA的使用交流可以到光年论坛。 因为现在大家都可以用它来探测google的排序算法,我相信会有很多的成果能发布在论坛上的。

自从去年我发布那篇介绍GSA的博客2个月后,因为有google的朋友也看这个博客,我猜google可能意识到了某些问题,所以google中止了GSA虚拟机版的更新,我这个版本是最新的一个版本。 我放这个版本出来是希望SEO行业从此不要道听途说或人云亦云,SEO是可以做得很科学的,SEO要长久发展下去就必须走规范化和标准化的道路。

利用Google Search Appliance 服务器做SEO

利用Google Search Appliance 服务器做SEO

 

昨天,Stephen留在中国的Google Search Appliance 服务器到了。这次Google Search Appliance(简称 GSA)和去年用的那个google mini不一样,这个GSA基本上可以看做是google mini的升级版本吧。

Google推出GSA的目的是让那些信息量暴增的企业和机构能用它建立自己的搜索引擎。它支持的格式有220多种,你可以用它来抓取和收录自己的博客、网站、数据库和网络文件夹等等。它是机器和软件全部打包在一起的。

Google官方网站介绍:http://www.google.com/enterprise/search/gsa.html

Google Search Appliance 正面3
Google Search Appliance 正面

主要特点有以下这些,随意看看就好:

– 有一个连接器管理工具,可以让你收录和那些非WEB格式的文档。如:word,pdf,flash 等等
– 如果使用 Feed API 和元数据搜索功能,可以为自己的论坛建立搜索功能。
– 还提供了强大的 Onebox 编程接口,可以让你在搜索结果中展现一些定制的信息。
– 强大的安全搜索功能支持多种身份认证方式,使用户在搜索结果中只见到自己有权限访问的文档。
– 为小规模文档设计了专门的网页排序算法。
– 用户可以定制搜索结果界面,甚至以 XML 格式的形式,来整合到您自己的应用中去。

这个对SEO也是非常有用的。为什么这么说呢?

你可以把这个GSA看做是google 的微缩版,它有爬虫,有索引库,有排序算法。它的的硬件和软件都是现在google.com这个网站正在用的东西。所以两者之间相似程度非常的高。我在过去操作google mini的时候已经证实:至少它的抓取机制和现在的google.com几乎是一摸一样的。

它的排序算法,我觉得也会有很大的相似度。当然不会一摸一样的,因为现有的GSA好像是依据06年的搜索技术改变而来,而以google每年450次的算法调整频率,到现在也相差比较多了。但是至少和现在的排序算法会有相当大的相似度。

还有一些有意思的东西,大家看上面提到的两个特点:“Onebox 编程接口”和“在搜索结果中只见到自己有权限访问的文档”。这其实就是现在google的一些应用。

Onebox在搜索引擎现有的排序算法中享有优先级,它的数据来源就是Google Base或其他google产品。这次GSA也提供了这种Onebox的编程接口,现在自己亲手给自己的GSA添加Onebox,一定会对你如何利用Onebox拿到更多流量有帮助的。

“在搜索结果中只见到自己有权限访问的文档”,这个就类似igoogle 。还有google其他一些产品,在搜索结果页面,你登陆了gmail看到的和不登陆看到的是不一样的。

还有更多的细节,会在以后详细讲述,会把GSA后台的操作也讲述一下。到时候你会对google webmaster tool这个工具有更深一层的理解。

下面直接上图,机器顶部:

 

GSA 机箱上印有大大的LOGO
GSA 机箱上印有大大的LOGO
机箱非常的重,可能有40多公斤。
为了保护里面的数据和硬件,机箱要用专用的螺丝刀才能打开。Google在服务器硬件上有很多专利的。
GSA 正面
GSA 正面
Google Search Appliance 背面1
Google Search Appliance 背面1
背面和一般的服务器没太大差别,但是注意它有一进一出两个网线口。设置它的时候需要用另一台电脑辅助。
Google Search Appliance 背面2
Google Search Appliance 背面2
来一张google机柜里的图:
机房
机柜
google mini (只有GSA一半大小)
google-mini-buy-search
利用GSA服务器做SEO测试,可以做出完美的SEO网页。
gsa侧面
gsa侧面

三月 30, 2016

MongoDB 查询上

Filed under: MongoDB — iseopad @ 7:09 上午

1.find

MongoDB使用find来进行查询.查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合.find的第一个参数

决定了要返回哪些文档.其形式也是一个文档,说明要查询的细节.

空的查询文档{}会匹配集合的全部内容.要是不指定查询文档,默认是{}.

如:db.users.find()返回集合users中的所有内容.

向查询文档中添加键值对,就意味着添加了查询条件.对绝大多数类型来说,整数匹配整数,布尔类型匹配布尔类型,字符串匹配

字符串.

 

2.指定返回的键

有时并不需要返回文档中的所有键值对返回.可以通过find或findOne的第二个参数来指定要返回的键.这样做能节省传输的

数据量,又能节省客户端解码文档的时间和内存消耗.

db.users.findOne({“name”:”refactor”},{“age”:1,”sex”:1})

只会将键为_id,age,sex的数据返回.

“_id”键总是会被返回.

也可以用第二个参数来剔除查询结果中的某个键值对.

如:

键name不会显示在返回的结果中

db.users.findOne({“name”:”refactor”},{“name”:0})

只会将键为age,sex的数据返回.”_id”键是不会返回的

db.users.findOne({“name”:”refactor”},{“age”:1,”sex”:1,”_id”:0})

 

3.查询条件

“$lt”,”$lte”,”$gt”,”$gte”分别对应<,<=,>,>=

如:

查询age >=18  <=30

db.users.find({“age”:{“$gte”:18,”$lte”:30}})

向文档增加键birthday

db.users.update(
{“name”:”refactor”},
{
“$set”:
{
“birthday”:new Date(“1989/10/26”)
}
}
)

查询birthday日期是1990-1-1之前的人

db.users.find({“birthday”:{“$lt”:new Date(“1990/01/01″)}})

 

使用”$ne”

查出所有name不等refactor1的文档,注意 文档中不存在键name的文档也会被查出来

db.users.find({“name”:{“$ne”:”refactor1″}})

 

使用or查询

MongoDB可以使用”$in”,”$or”

使用”$in”

查询出pageViews为10000,20000的数据

db.users.find({pageViews:{“$in”:[10000,20000]}})

“$in”可以指定不同类型的条件和值,如正在将用户的ID号迁移成用户名的过程中,要做到两者兼顾的查询:

db.users.find({“user_id”:{“$in”:[12345,”refactor”]}})

这会匹配user_id为12345和”refactor”的文档.

要是 “$in”的数组只有一个值和直接匹配这个值效果是一样的.

db.users.find({“pageViews”:{“$in”:[10000]}})
db.users.find({“pageViews”:10000})

使用”$nin”返回与数组中所有条件都不匹配的文档

如 查出所有pageViews不等10000,20000的文档,注意 文档中不存在键pageViews的文档也会被查出来

db.users.find({“pageViews”:{“$nin”:[10000,20000]}})

 

“$in”能对单个键进行or查询.

使用”$or”

db.users.find(
{
“$or”:
[
{“pageViews”:{“$in”:[10000,20000]}},
{“url”:”http://www.cnblogs.com/refactor”}
]
}
)

这将查询出pageViews是10000,20000或url是http://www.cnblogs.com/refactor的文档.

注意:使用普通的and查询时,要尽量将最苛刻的条件放在前面.

 

使用”$not”

“$not”可以用在任何条件之上.

如:

db.users.find(
{“id_num”:{“mod”:[5,1]}}
)

这会查询出id_num取模后值为1的文档.

db.users.find(
{“id_num”:{“$not”:{“mod”:[1,5]}}}
)

 

4.条件句的规则

在查询中,”$lt”在内层文档,在更新中”$inc” 是外层文档的键.

条件句是内层文档的键,修改器是外层文档的键.

可对一个键应用多个条件,但一个键不能对应多个更新修改器.

 

5.特定于类型的查询

null可以匹配自身,而且可以匹配”不存在的”

 

能查出url 是”http://www.cnblogs.com/refactor”,pageViews为null的文档

db.users.find({“url”:”http://www.cnblogs.com/refactor”,”pageViews”:null})

能查出pageViews为null的文档,不存在键pageViews的也能查出来

db.users.find({“pageViews”:null})

能查出url 是”http://www.cnblogs.com/refactor”,pageViews为null的文档,但不能查出不存在键pageViews的的文档
db.users.find({“url”:”http://www.cnblogs.com/refactor”,”pageViews”:{“$in”:[null],”$exists”:true}})

MongoDB没有”$eq”操作符,但是只有一个元素的”$in”的操作效果是一样的

 

如果仅仅想要匹配键值为null的文档,既要检查该键的值是否为null,还要通过”$exists”条件判断该键是不是存在.

 

6.正则表达式

正则表达式能够灵活有效的匹配字符串.

查找所有名包含refact或Refact的用户,使用正则表达式执行忽略大小写的匹配

db.users.find({“name”:/refact/i})

系统可以接受正则表达式标识(i),但不是一定有.现在匹配了各种大小写形式的refact.

MongoDB可以为前缀型正则表达式(如:/^refactor/)查询创建索引.所以这种类型的查询非常高效.

正则表达式也可以匹配自身

db.users.find({“name”:/refact/})

可以查出name为/refact/的文档.

 

7.查询数组

数组很大多数情况下可以这样理解:每一个元素都是整个键的值.

db.users.findOne({“userName”:”refactor”,”emails”:”295240648@qq.com”})能匹配到

 

使用”$all”

如果需要多个元素来匹配数组,就要用”$all”

db.users.insert({“userName”:”refactor”,emails:[“295240648@qq.com”,”295240648@163.com”,”295240648@126.com”]})
db.users.insert({“userName”:”refactor”,emails:[“295240648@qq.com”,”295240648@126.com”,”295240648@111.com”]})
db.users.insert({“userName”:”refactor”,emails:[“295240648@126.com”,”295240648@163.com”,”295240648@111.com”]})

要找到邮箱有”295240648@163.com”又有”295240648@126.com”,顺序无关紧要的文档
db.users.find(
{
“emails”:
{
“$all”:
[
“295240648@163.com”,
“295240648@126.com”
]
}
}
)

要是只对一个元素的数组使用”$all”就和不用”$all”是一样的,如

db.users.find({“emails”:{“$all”:[“295240648@126.com”]}})
db.users.find({“emails”:”295240648@126.com”})

效果是一样的.

 

也可以精确的匹配数组

db.users.find({“userName”:”refactor”,emails:[“295240648@qq.com”,”295240648@163.com”,”295240648@126.com”]})

 

若想查询数组指定位置的元素,需要使用key.index语法指定下标

db.users.find({“emails.1″:”295240648@163.com”})

 

使用”$size”

“$size”可以查询指定长度的数组

查询数组长度为3的数组

db.users.find({“emails”:{“$size”:3}})

常见的查询是数组长度范围的查询.”$size”并不能与其他查询子句组合(如:”$gt”),但是这种查询可以通过

在文档中添加一个”size”键的方式来实现.这样每一次向指定数组添加元素的时候,同时增加”size”值.原来这样

的更新:

db.users.update({“$push”:{“emails”:”295240648@139.com”}})

变成这样的更新:
db.users.update({“$push”:{“emails”:”295240648@139.com”},”$inc”:{“size”:1}})

这样就可以这样查询了

db.users.find({“size”:{“$gt”:3}})

 

使用”$slice”查询

find的第二个参数是可选的,可以指定返回那些键,”$slice”返回数组的一个子集合

返回emails数组的前两个元素

db.users.find({“userName”:”refactor”},{“emails”:{“$slice”:2}})

返回emails数组的后两个元素

db.users.find({“userName”:”refactor”},{“emails”:{“$slice”:-2}})

返回emails数组的第2个和第11个元素.如果数组不够11个,则返回第2个后面的所有元素

db.users.find({“userName”:”refactor”},{“emails”:{“$slice”:[1,10]}})

“$slice”默认将返回文档中的所有键.

 

三月 28, 2016

C#编写FTP客户端软件

Filed under: C# — 标签: — iseopad @ 5:33 下午

1 介绍

我知道。网上有很多现成的FTP软件。但是。我们也想要了解FTP的一些底层机构,因此。 这个开源的项目在你学习FTP知识的时候也许对你有些帮组。程序的界面看起来像FileZilla,FileZilla虽然流行但是有些bug,当我打开我博客的时候总是有问题。我需要通过FTP连接我的服务器。发送文件,下载文件等等。因为。我决定写我自己的软件来处理所有的情况。FileZilla足够好。但它不是我的。

 

2 背景

 

看看我们已经知道的。我们知道FTP是一个标准的基于TCP网络协议。用于从一个主机向另一个主机传输文件。它是一个C/S架构。

 

图2

 

FTP程序曾经是基于命令行的。我们仍沿可以通过cmd.exe连接FTP服务器。因为FTP的确可以通过命令来操作。举个例子。我们可以在命令行使用“stor”命令来发送文件。为了完成这些请求。FTP服务器需要一直运行等待即将到来的客户端请求。我们可以从来自维基百科的解释更好的理解FTP:

 

客户端计算机可以通过服务器的21端口和服务器通信。叫做控制连接。它在一次会话期间保持开放。第一次连接的时候。叫做数据连接,服务器可以对客户端打开20端口(主动模式),建立一条数据通路,连接上客户端传输数据。或者客户端打开一个随机的端口(被动模式),去连接服务器,来传输数据。控制连接使用一个类似Telnet的协议,被用作客户端和服务器会话管理(命令,标识,密码)。。比如。”RETR filename”  会从服务器端下载文件。

图三

一个完整的FTP文件传输需要建立两种类型的连接,一种为文件传输下命令,称为控制连接,另一种实现真正的文件传输,称为数据连接。

服务器 通过三位ASCII的数字状态码,可能包含可选的描述信息,在控制连接上做出回应。比如。“200”或者是“200 OK”,表示上一条命令成功了。数字代表编号,描述信息给出了一些说明(比如“OK”),或者可能是一些需要的参数(比如需要帐号来存储文件),那么我们需要怎么做呢。很明显。发送命令,接收“OK”回应,发送数据。接收数据。完了。但是首先需要服务器已经准备好了。FTP服务器可以在主动和被动两种模式下运行。主动模式是基于服务器的连接而被动模式是基友客户端的连接。继续看。

在主动连接中,客户端把自己的ip和端口发送给服务器。然后服务器尝试连接到客户端,但是可能会因为防火墙的原因而被拒绝。我们在windows上都会使用反病毒/自带防火墙。是吧。那么我们来看看被动模式

在被动连接中。服务器通过一个“PASV”命令把自己的ip和端口发送给客户端。然后客户端通过该IP尝试连接服务器。对于发送文件非常有用。当我们发送文件的时候。优先使用“PASV”模式,如你们所说。大多数协议。像FTP/HTTP 使用ASCII编码,因为全球可用。因此我们会使用这种编码。你可以从下面得到FTP的命令列表

主动和被动都是对于服务器端来说的

3 使用代码

现在我们已经为编写软件做好准备了。我们写些有用的代码吧。:)首先。我们“打开文件对话框”,集成到我们的窗体里。

3.1 资源管理器组件

我们需要一个资源管理器组件在软件界面可以看到我们所有的文件。这样我们才可以选择哪些文件来发送到FTP服务器,新建一个Windows窗体控件库(下载包中提供了)

图四

最后看起来样子是上面这样。先添加一个TreeView,一些按钮,和一个搜索功能

TreeView.Nodes.Clear();

TreeNode nodeD = new TreeNode();

nodeD.Tag = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

nodeD.Text = "Desktop";

nodeD.ImageIndex = 10;

nodeD.SelectedImageIndex = 10;

TreeView.Nodes.Add(nodeD);

就像上面代码展示的那样。我们需要添加地一个主节点。我的文档。我的电脑等等。然后获得子目录。

string[] dirList;
dirList = Directory.GetDirectories(parentNode.Tag.ToString());
Array.Sort(dirList);
if (dirList.Length == parentNode.Nodes.Count)
    return;
for (int i = 0; i < dirList.Length; i++)
{
    node = new TreeNode();
    node.Tag = dirList[i]; 
    node.Text = dirList[i].Substring(dirList[i].LastIndexOf(@"\") + 1);
    node.ImageIndex = 1;
    parentNode.Nodes.Add(node);
}

 

可以从下载包里看到完整的代码。我们还应该处理鼠标单击事件。

现在我们有了一个资源管理器。还有FTP和VS所需要的所有信息。

首先,我们连接服务器。我们应该怎么做呢?

FTPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
AppendText(rchLog,"Status : Resolving IP Address\n",Color.Red);
remoteAddress = Dns.GetHostEntry(Server).AddressList[0];
AppendText(rchLog, "Status : IP Address Found ->" + remoteAddress.ToString() + "\n", Color.Red);
addrEndPoint = new IPEndPoint(remoteAddress, Port);
AppendText(rchLog,"Status : EndPoint Found ->" + addrEndPoint.ToString() + "\n", Color.Red);
FTPSocket.Connect(addrEndPoint);

 

是的。我们需要一个socket连接到服务器 ,然后发送命令
AppendText(rchLog, "Command : " + msg + "\n", Color.Blue);
Byte[] CommandBytes = Encoding.ASCII.GetBytes((msg + "\r\n").ToCharArray());
FTPSocket.Send(CommandBytes, CommandBytes.Length, 0);
//read Response
ReadResponse();

我们发送命令到服务器。服务器以他自己的语言来响应。我们需要理解他。响应包括3位数字和一些解释。

 

private string SplitResponse()
{
    try
    {
        while (true)
        {
            Bytes = FTPSocket.Receive(Buffer, Buffer.Length, 0); //Number Of Bytes (Count)
            StatusMessage += Encoding.ASCII.GetString(Buffer, 0, Bytes); //Convert to String
            if (Bytes < Buffer.Length)  //End Of Response
                break;
        }
        string[] msg = StatusMessage.Split('\n');
        if (StatusMessage.Length > 2)
            StatusMessage = msg[msg.Length - 2];  //Remove Last \n
        else
            StatusMessage = msg[0];
        if (!StatusMessage.Substring(3, 1).Equals(" "))
            return SplitResponse();
        for (int i = 0; i < msg.Length - 1; i++)
            AppendText(rchLog, "Response : " + msg[i] + "\n", Color.Green);
        return StatusMessage;
    }
    catch(Exception ex)
    {
        AppendText(rchLog, "Status : ERROR. " +ex.Message+ "\n", Color.Red);
        FTPSocket.Close();
        return "";
    }
}

 

完了。现在我们可以下载,上传,重命名。或者删除了。

4 FTP命令列表

命令 描述
ABOR 中断一个活动的文件传输
ACCT 系统帐号信息
ADAT 认证/安全数据
ALLO 分配空间来接收文件
APPE 添加文件到服务器
AUTH 认证/安全机制
CCC 清除命令通道
CDUP 转到父目录
CONF 机密性保护命令
CWD 改变服务器上的工作目录
DELE 删除服务器上的指定文件
ENC 机密保护通道
EPRT 指定一个服务器应该连接的扩展地址和端口
EPSV 进入扩展的被动模式
FEAT 得到服务器提供的功能列表
HELP 返回指定命令信息
LANG 返回语言信息
LIST 如果是文件名列出文件信息,如果是目录则列出文件列表
LPRT 指定一个服务器应该连接的长地址和端口
LPSV 进入长被动模式
MDTM 返回文件最近修改时间
MIC 完整的保护命令
MKD 创建目录
MLSD 列出指定目录的内容
MLST 在命令行上列出对象的精确信息
MODE 传输模式(S=流模式,B=块模式,C=压缩模式)
NLST 列出指定目录内容
NOOP 无动作,(虚包,来自常连接中)
OPTS 选择一个功能的选项
PASS 验证密码
PASV 进入被动模式
PBSZ 保护缓冲区大小
PORT 指定服务器应该连接的地址和端口
PROT 数据通道保护级别
PWD 显示当前工作目录
QUIT 从FTP服务器上退出登录
REIN 重新初始化登录状态连接
REST 由指定点重启文件传递
RETR 传递文件副本
RMD 在服务器上删除指定目录
RNFR 从旧名称重命名
RNTO 到新名称
SITE 向远程服务器发送指定命令
SIZE 返回文件大小
SMNT 挂载指定文件结构
STAT 返回当前状态
STOR 储存(复制)文件到服务器上
STOU 储存文件到服务器指定文件上
STRU 设置结构(F=文件,R=记录,P=页面)
SYST 返回服务器使用的操作系统
TYPE 传输模式(A=ASCII,E=EBCDIC,I=binary)
USER 验证用户
XCUP 跳到当前工作路径的父目录
XMKD 新建目录
XPWD 输出当前工作目录
XRMD 删除目录

 

5 返回码列表

  • 2xx –返回成功
  • 4xx or 5xx – 返回失败
  • 1xx or 3xx – 错误或不完整的回复

第二位定义了错误的类型

  • x0z – 语法 – 有语法错误.
  • x1z – 信息 – 请求提供信息
  • x2z – 连接 – 说明控制或数据连接有问题
  • x3z – 账户认证 – 登录或者是账户认证有问题.
  • x4z – 未定义
  • x5z – 文件系统 – 可能是服务器文件系统有问题。

 

Demo 下载

C#编写FTP客户端

6 许可

本文包括源代码和文件在CPOL下授权。

 

原文地址:File-Transfer-Protocol-FTP-Client

十二月 4, 2015

php文件操作和文件夹操作

Filed under: PHP — iseopad @ 6:43 下午

dirname(__FILE__) 取到的是当前文件的绝对路径,也就是说,比起相对路径,查找速度是最快的。

本文实例讲述了php读取目录及子目录下所有文件名的方法,分享给大家供大家参考。具体实现方法如下:

一般来说php中读取目录下的文件名的方式确实不少,最简单的是scandir,具体代码如下:

复制代码 代码如下:
$dir=”./caxa/”;
$file=scandir($dir);
print_r($file);

稍微复杂点的,来自于php手册:

复制代码 代码如下:
$dir = “/etc/php5/”;
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
echo “filename: $file : filetype: ” . filetype($dir . $file) . “\n”;
} closedir($dh);
}
}

这些都只能读取当前指定目录下的文件,对子目录中的文件则无法读取。原来自己写过一个循环删除所有目录的一段代码,需要逐个子目录删除所有文件,包括多层。但是只需要读出文件名,稍微复杂点,网上找到一个能用,原始代码有错误提示,改了一下引用&$data的地方,如下所示:

复制代码 代码如下:
function searchDir($path,&$data){
if(is_dir($path)){
$dp=dir($path);
while($file=$dp->read()){
if($file!=’.’&& $file!=’..’){
searchDir($path.’/’.$file,$data);
}
}
$dp->close();
}
if(is_file($path)){
$data[]=$path;
}
}function getDir($dir){
$data=array();
searchDir($dir,$data);
return   $data;
}print_r(getDir(‘.’));

希望本文所述对大家的PHP程序设计有所帮助。

PHP中文件读、写、删的操作(PHP中对文件和目录操作)

 

一:目录操作
首先介绍的是一个从目录读取的函数,opendir(),readdir(),closedir(),使用的时候是先打开文件句柄,而后迭代列出:

复制代码 代码如下:
<?php
$base_dir = “filelist/”;
$fso = opendir($base_dir);
echo $base_dir.”<hr/>” ;
while($flist=readdir($fso)){
echo $flist.”<br/>” ;
}
closedir($fso)
?>

这是讲返回文件目录下面的文件已经目录的程序(0文件将返回false).
有时候需要知道目录的信息,可以使用dirname($path)和basename($path),分别返回路径的目录部分和文件名名称部分,可用disk_free_space($path)返回看空间空余空间.
创建命令:
  mkdir($path,0777)
,0777是权限码,在非window下可用umask()函数设置.
rmdir($path)
将删除路径在$path的文件.
dir — directory 类也是操作文件目录的重要类,有3个方法,read,rewind,close,这是一个仿面向对象的类,它先使用的是打开文件句柄,然后用指针的方式读取的.,这里看php手册:

复制代码 代码如下:
<?php
$d = dir(“/etc/php5”);
echo “Handle: ” . $d->handle . “\n”;
echo “Path: ” . $d->path . “\n”;
while (false !== ($entry = $d->read())) {
echo $entry.”\n”;
}
$d->close();
?>
[code]
输出:
Handle: Resource id #2
Path: /etc/php5
.
..
apache
cgi
cli
文件的属性也非常重要,文件属性包括创建时间,最后修改时间,所有者,文件组,类型,大小等
下面我们重点谈文件操作.
二:文件操作
读文件
首先是一个文件看能不能读取(权限问题),或者存在不,我们可以用is_readable函数获取信息.:
[code]
<?php
$file = ‘dirlist.php’;
if (is_readable($file) == false) {
die(‘文件不存在或者无法读取’);
} else {
echo ‘存在’;
}
?>

判断文件存在的函数还有file_exists(下面演示),但是这个显然无is_readable全面.,当一个文件存在的话可以用

复制代码 代码如下:
<?php
$file = “filelist.php”;
if (file_exists($file) == false) {
die(‘文件不存在’);
}
$data = file_get_contents($file);
echo htmlentities($data);
?>

但是file_get_contents函数在较低版本上不支持,可以先创建文件的一个句柄,然后用指针读取全部:

复制代码 代码如下:
$fso = fopen($cacheFile, ‘r’);
$data = fread($fso, filesize($cacheFile));
fclose($fso);

还有一种方式,可以读取二进制的文件:
$data = implode(”, file($file));
详细学习PHP中对文件和目录的操作方法
一:引论
在任何计算机设备中,文件是都是必须的对象,而在web编程中,文件的操作一直是web程序员的头疼的地方,而,文件的操作在cms系统中这是必须的,非常有用的,我们经常遇到生成文件目录,文件(夹)编辑等操作,现在我把php中的这些函数做一详细总结并实例示范如何使用.,关于对应的函数详细介绍,请查阅php手册.此处只总结重点.和需要注意的地方.(这在php手册是没有的.)
二:目录操作
  首先介绍的是一个从目录读取的函数,opendir(),readdir(),closedir(),使用的时候是先打开文件句柄,而后迭代列出:

复制代码 代码如下:
<?php
$base_dir = “filelist/”;
$fso = opendir($base_dir);
echo $base_dir.”<hr/>” ;
while($flist=readdir($fso)){
echo $flist.”<br/>” ;
}
closedir($fso)
?>

这是讲返回文件目录下面的文件已经目录的程序(0文件将返回false).
有时候需要知道目录的信息,可以使用dirname($path)和basename($path),分别返回路径的目录部分和文件名名称部分,可用disk_free_space($path)返回看空间空余空间.
创建命令:
mkdir($path,0777),0777是权限码,在非window下可用umask()函数设置.
rmdir($path)将删除路径在$path的文件.
dir — directory 类也是操作文件目录的重要类,有3个方法,read,rewind,close,这是一个仿面向对象的类,它先使用的是打开文件句柄,然后用指针的方式读取的.,这里看php手册:

复制代码 代码如下:
<?php
$d = dir(“/etc/php5”);
echo “Handle: ” . $d->handle . “\n”;
echo “Path: ” . $d->path . “\n”;
while (false !== ($entry = $d->read())) {
echo $entry.”\n”;
}
$d->close();
?>

输出:
Handle: Resource id #2
Path: /etc/php5
.
..
apache
cgi
cli
文件的属性也非常重要,文件属性包括创建时间,最后修改时间,所有者,文件组,类型,大小等
下面我们重点谈文件操作.
三:文件操作
读文件
首先是一个文件看能不能读取(权限问题),或者存在不,我们可以用is_readable函数获取信息.:

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
if (is_readable($file) == false) {
die(‘文件不存在或者无法读取’);
} else {
echo ‘存在’;
}
?>

判断文件存在的函数还有file_exists(下面演示),但是这个显然无is_readable全面.,当一个文件存在的话可以用

复制代码 代码如下:
<?php
$file = “filelist.php”;
if (file_exists($file) == false) {
die(‘文件不存在’);
}
$data = file_get_contents($file);
echo htmlentities($data);
?>

但是file_get_contents函数在较低版本上不支持,可以先创建文件的一个句柄,然后用指针读取全部:
$fso = fopen($cacheFile, ‘r’);
$data = fread($fso, filesize($cacheFile));
fclose($fso);
还有一种方式,可以读取二进制的文件:
$data = implode(”, file($file));
写文件
和读取文件的方式一样,先看看是不是能写:

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
if (is_writable($file) == false) {
die(“我是鸡毛,我不能”);
}
?>

能写了的话可以使用file_put_contents函数写入:

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
if (is_writable($file) == false) {
die(‘我是鸡毛,我不能’);
}
$data = ‘我是可鄙,我想要’;
file_put_contents ($file, $data);
?>

file_put_contents函数在php5中新引进的函数(不知道存在的话用function_exists函数先判断一下)低版本的php无法使用,可以使用如下方式:
$f = fopen($file, ‘w’);
fwrite($f, $data);
fclose($f);
替换之.
写文件的时候有时候需要锁定,然后写:

复制代码 代码如下:
function cache_page($pageurl,$pagedata){
if(!$fso=fopen($pageurl,’w’)){
$this->warns(‘无法打开缓存文件.’);//trigger_error
return false;
}
if(!flock($fso,LOCK_EX)){//LOCK_NB,排它型锁定
$this->warns(‘无法锁定缓存文件.’);//trigger_error
return false;
}
if(!fwrite($fso,$pagedata)){//写入字节流,serialize写入其他格式
$this->warns(‘无法写入缓存文件.’);//trigger_error
return false;
}
flock($fso,LOCK_UN);//释放锁定
fclose($fso);
return true;
}

复制,删除文件
php删除文件非常easy,用unlink函数简单操作:

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
$result = @unlink ($file);
if ($result == false) {
echo ‘蚊子赶走了’;
} else {
echo ‘无法赶走’;
}
?>

即可.
复制文件也很容易:

复制代码 代码如下:
<?php
$file = ‘yang.txt’;
$newfile = ‘ji.txt’; # 这个文件父文件夹必须能写
if (file_exists($file) == false) {
die (‘小样没上线,无法复制’);
}
$result = copy($file, $newfile);
if ($result == false) {
echo ‘复制记忆ok’;
}
?>

可以使用rename()函数重命名一个文件夹.其他操作都是这几个函数组合一下就能实现的.
获取文件属性
我说几个常见的函数:
获取最近修改时间:

复制代码 代码如下:
<?php
$file = ‘test.txt’;
echo date(‘r’, filemtime($file));
?>

返回的说unix的时间戳,这在缓存技术常用.
相关的还有获取上次被访问的时间fileatime(),filectime()当文件的权限,所有者,所有组或其它 inode 中的元数据被更新时间,fileowner()函数返回文件所有者 $owner = posix_getpwuid(fileowner($file));(非window系统),ileperms()获取文件的权限,

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
$perms = substr(sprintf(‘%o’, fileperms($file)), -4);
echo $perms;
?>

filesize()返回文件大小的字节数:

复制代码 代码如下:
<?php
// 输出类似:somefile.txt: 1024 bytes
$filename = ‘somefile.txt’;
echo $filename . ‘: ‘ . filesize($filename) . ‘ bytes’;
?>

获取文件的全部信息有个返回数组的函数stat()函数:

复制代码 代码如下:
<?php
$file = ‘dirlist.php’;
$perms = stat($file);
var_dump($perms);
?>

那个键对应什么可以查阅详细资料,此处不再展开.
四:结束语
上面我简要的总结了一下几个文件操作,如果您熟练掌握以上列出的函数,已经在操作的时候没什么大的问题,php文件操作的函数变化比较快,现在已经非常强大了,文件这部分也是学习php非常重要的一部分,希望不要忽略.

十二月 3, 2015

指定关键词跳转代码

Filed under: Javascript — iseopad @ 8:48 下午

刚刚看到五柳大神一周前发的帖子,是关于关键词跳转的代码。我最近刚好在学习JS,就仔细看了下。发现,我看不懂,哈哈!
不过,class是调用CSS或JS时用的类,在五柳大神的帖子里没有外部调用,也没有内部样式之类的,所以可以确定,<span></span>可以去掉。所以最后剩下的代码是

  1. <script type=”text/javascript”>
  2. var d=document.referrer;
  3. var re=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E5%A4%A7%E5%8F%91888))/;

复制代码

我还是分行写比较清爽,就这样你看懂了吗?最后一行%E5%A4%A7%E5%8F%91888是不是看不懂?这就是关键词!哈哈,就是这么简单!
五柳大神估计是网上找的,要么是看的别人网站源码,要么是看的帖子,不深究。我想说的是,这是用的URL编码加密的,UTF-8,给个链接http://tool.chinaz.com/Tools/URLEncode.aspx
我是好人,不谢!
如果只是这样没必要新开一帖,直接回复就是了。但是,我要扩展五柳大神的代码,请看好。先把下面代码另存为js文件,然后可以放在网页的任何位置,当然不影响网页加载速度优先。

  1. [hide]var surl=document.location.href+”&from=”+from;//自定义的一个来源 可以不要
  2. var s=document.referrer;
  3. /*****
  4. 思路大概是:
  5. 获取从百度来的关键词 用我们自己的关键词匹配 匹配对了 跳转到指定网页
  6. 跳转到一个php文件的好处 是用表单做跳转 对seo影响较小 而且还可以在php里面加些自定义判断功能
  7. 其中有用到 站长工具(http://tool.chinaz.com/)的 url编码解码  大小写转换
  8. js的  .test()  函数  是看能是否字符串匹配成功
  9. *****/
  10. var re=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E9%A3%8E%E6%B9%BF))/;  //风湿 url编码 格式为utf-8的
  11. var re1=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E9%AA%A8%E8%B4%A8%E5%A2%9E%E7%94%9F))/;  //骨质增生 url编码
  12. var re2=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E9%A2%88%E6%A4%8E%E7%97%85))/;  //颈椎病 url编码
  13. var re3=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E5%BC%BA%E7%9B%B4%E6%80%A7%E8%84%8A%E6%9F%B1%E7%82%8E))/;  //强直性脊柱炎 url编码
  14. var re4=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E7%97%9B%E9%A3%8E))/;  //痛风 url编码
  15. var re5=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E8%85%B0%E6%A4%8E%E7%97%85))/;  //腰椎病 url编码
  16. var re6=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E8%82%A9%E5%91%A8%E7%82%8E))/;  //肩周炎 url编码
  17. var re7=/((wd|q|w|p|query)(=)([%A-Z0-9]*)(%E5%93%81%E7%89%8C))/;  //品牌 url编码
  18. var curl=window.location.href;
  19. if(re.test(s))
  20. {
  21.     var iii = decodeURI(‘%E9%A3%8E%E6%B9%BF’);
  22.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);  //get传值 到tiaozhuan.php
  23. }
  24. else if(re1.test(s))
  25. {
  26.     var iii = decodeURI(‘%E9%AA%A8%E8%B4%A8%E5%A2%9E%E7%94%9F’);
  27.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  28. }
  29. else if(re2.test(s))
  30. {
  31.     var iii = decodeURI(‘%E9%A2%88%E6%A4%8E%E7%97%85’);
  32.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  33. }
  34. else if(re3.test(s))
  35. {
  36.     var iii = decodeURI(‘%E5%BC%BA%E7%9B%B4%E6%80%A7%E8%84%8A%E6%9F%B1%E7%82%8E’);
  37.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  38. }
  39. else if(re4.test(s))
  40. {
  41.     var iii = decodeURI(‘%E7%97%9B%E9%A3%8E’);
  42.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  43. }
  44. else if(re5.test(s))
  45. {
  46.     var iii = decodeURI(‘%E8%85%B0%E6%A4%8E%E7%97%85’);
  47.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  48. }
  49. else if(re6.test(s))
  50. {
  51.     var iii = decodeURI(‘%E8%82%A9%E5%91%A8%E7%82%8E’);
  52.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  53. }
  54. else if(re7.test(s))
  55. {
  56.     var iii = decodeURI(‘%E5%93%81%E7%89%8C’);
  57.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php?a=’+iii+’&from=’+from,curl,1);
  58. }
  59. else
  60. {
  61.     yh_turn(‘http://www.120xbk.com/swt/tiaozhuan.php’,surl,1);
  62. }
  63. //模拟提交表单跳转
  64. function yh_turn(url,domain,from)
  65. {
  66.     function isURL(url){
  67.         return(/^(http(s?))\:\/\/([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?([\/\?]\S*)?$/.test(url));
  68.     }
  69.     if(!isURL(url))return false;
  70.     function doSubmit()
  71.     {
  72.         //hidden body
  73.         document.writeln(‘<style type=”text/css”>body{display:none;}</style>’);
  74.         //var tjurl = url+’?’+domain;
  75.         var tjurl = url;
  76.         document.write(‘<form name=”myform” id=”tj” action=”‘+tjurl+'” method=”post” target=”_self”></form>’);
  77.         //document.myform.submit();
  78.         setTimeout(‘document.getElementById(“tj”).submit()’,500);
  79.     }
  80.     if(from==1){
  81.         var s=document.referrer;
  82.         if(s&&(s.indexOf(“baidu.com”)>0||s.indexOf(“google.com”)>0||s.indexOf(“soso.com”)>0||s.indexOf(“sogou.com”)>0)){
  83.             doSubmit();
  84.         }
  85.     }
  86.     if(from==0){
  87.         doSubmit();   //不经过百度 默认都跳转
  88.     }
  89. } [/hide]

复制代码

然后新建个php的跳转文件

  1. <?php
  2. $refer = $_SERVER[‘HTTP_REFERER’];
  3. $from = $_GET[‘from’];  //如果有来源 接收来源
  4. $a = $_GET[‘a’];
  5. $b = urldecode($a);  //将字符串以URL解码
  6. //处理变量$refer
  7. $str=substr($refer,7);//去除前面
  8. $n=strpos($str,’/’);//寻找位置
  9. if ($n) $str=substr($str,0,$n);//删除后面
  10. $url_this = “http://”.$_SERVER [‘HTTP_HOST’];
  11. header(“HTTP/1.1 301 Moved Permanently”);
  12. if($refer)
  13. {
  14.     switch($b)
  15.     {
  16.         case ‘风湿’: header(“location:”.$url_this.”/tszl/20110805-527.html?”.$str.”&”.$from);break;
  17.         case ‘骨质增生’:header(“location:”.$url_this.”/bingli/gjzx/20110702-272.html?”.$str.”&”.$from);break;
  18.         case ‘颈椎病’:header(“location:”.$url_this.”/tszl/20110805-546.html?”.$str.”&”.$from);break;
  19.         case ‘强直性脊柱炎’:header(“location:”.$url_this.”/tszl/20110702-284.html?”.$str.”&”.$from);break;
  20.         case ‘痛风’:header(“location:”.$url_this.”/tszl/20110702-285.html?”.$str.”&”.$from);break;
  21.         case ‘腰椎病’:header(“location:”.$url_this.”/tszl/20110702-287.html?”.$str.”&”.$from);break;
  22.         case ‘肩周炎’:header(“location:”.$url_this.”/tszl/20110702-263.html?”.$str.”&”.$from);break;
  23.         case ‘品牌’:header(“location:”.$url_this.”/tszl/?”.$str.”&”.$from);break;
  24.         default: header(“location:”.$url_this.”?”.$str.”&”.$from);break;
  25.     }
  26. }
  27. else
  28.     exit;
  29. ?>

复制代码

OK,功能实现!如果你看到这里,基本上说明你看懂了,哈哈!请给我评分送豆,每人每天都有一定数量的送豆机会,不会扣除你的黑豆的!~!

九月 19, 2015

怎样利用外链保持外贸网店的关键词排名

Filed under: SEO技术 — iseopad @ 1:31 上午

对于辛辛苦苦优化好的网站,如何保持它在谷歌的排名,或者能够排得更前,以下是摘自互联网的一片文章,讨论如何利用和管理好外链,现与大家分享。

 

首先我们从外链来分析一个网站的排名。现在很大一部分中小型网站是依赖于外部链接而生存,这就意味着,外链被删除或者外链效力的降低将会直接影响的排名的波动。

 

很多SEO使用单一的链接,例如BLOG留言,论坛回复,黑链等。排名上的快,下的也快,一个网站牵扯SEO大部分精力来进行后期的维护,没有办法批量化进行SEO工作。也有部分SEO采用多元化的链接形式,稳定与不稳定的外链共存,也往往会被部分链接影响到排名的波动。所以,重要的还是挖掘自己的核心竞争力。

 

针对这个问题,最简单的方式,是对外链进行最大化的优化,用同样的资源,获取更稳定的排名。

 

我们用金字塔形的链接构造来解决这个问题,金字塔可以很形象的解释这个外链的网络。想象一下金字塔的模型,首先,它是从上往下越来越多,其次,它分层明 确。

 

我发现例一个金字塔模式的外链结构,它把外链划分成了多层的结构

 

第一层 是我们要推的主站

 

第二层 相关度高的同类网站

 

第三层 个人建立的独立域名BLOG

 

第四层 第三方的免费BLOG

 

第五层 BLOG留言,论坛回复等

 

先来解释这个结构互相之间的关系。

 

首先,大家都能看明白的是,他们是从下往上一层推一层的关系。其次,从第二层开始,每一层本身也有互推的关系,也就是一个小的站群网络。最后,不仅是某层 对上面一层,比如第五层,对第一层,或者第四层对第二层都要起到推广的作用,中间是没有断层的。

 

然后我们来明白这个金字塔结构的是什么。

 

首先,这是一个概念,不是一个执行方法,并不是说你的金字塔一定要建立五层,也并不是说一定要用个人 BLOG或者某种链接,也可以用软文,书签,目录等代替其中某层,根据不同公司或者SEO的情况来制定本身网站的外链结构。

 

其次,要了解目的,你才能明白这个金字塔存在的意义。

 

这个金字塔存在的意义,是让我们的外链有足够的稳定性。很多人可能看出来了,金字塔所在的层数和它的稳定性有绝对的关系,我们把越稳定的外链形式放在越靠 前的层次。所以,你可以想象,如果层数足够多,当你的某些不稳定性的链接,对其上面一层造成了不稳定的权重,而这种不稳定性的权重通过层层上传会逐渐变小,直到最上面一层,无限接近于零。

 

最后,这个金字塔形的外链的重点在于,一个金字塔内部各层之间以及互相之间的链接关系与当你有多个主站,多个金字塔结构的外链网络后这些各个金字塔之间的互相联系的关系。

 

很多人会认为这是一个站群的理论,其实不然,大部分站群其实是没有层次关系的,也就是用站群加一些其他链接放在同一个层次来推广上面的主站而已。也有很 多人可能觉得这个结构会产生大量人力物力,其实也不然,这是一个对本身外链结构规整化的概念,根据网站本身的外链情况进行分组分层,最终达到同样的资源,最大化的利用和整合。

 

上面是外链方面稳定性的过程,下面讲一下怎么样通过网站本身的内容来稳定一个网站的排名

 

首先,我们利用到相关关键词的原理,假设A是主要关键词,B,C,D是相关关键词,并且在网站内都有对应的页面。很多SEO在对网站执行操作的过程中可能会发现,当你的A词排名上升以后,会对B,C,D词起到一个带动的作用,这些词可能你没有去做过任何的处理和推 广,也会排名跟着上升。

 

我们反向的利用这个理论来通过内容稳定关键词的排名

 

首先,我们在选定一个主要关键词A后,将所有的相关关键词B,C,D找出来,然后制定好着陆页面,可以是首页,也可以是其他页面,或者也可以写新的文章。

 

然后我们对这些关键词B,C,D来进行推广,因为大部分时候这类的词会比主词要好获得排名,首先你会发现,在推广相关关键词B,C,D的过程中,假设不对主词A做任何推广,A词都有排名的上升。

 

最后,当你有大量的相关关键词B,C,D排名靠前后并且稳定后,你会发现,你的主词A在搜索引擎中的表现非常的优秀,并且异常的稳定。顺便提下,如果你需要运用这种稳固排名的方法,那么你很有可能需要知道“网站维护需要技巧”,必须寻找一个良好合理的方法来,才能够提高自己的工作效率。

九月 5, 2015

Randomly shuffle a List [duplicate]

Filed under: C# — iseopad @ 12:00 上午
2down votefavorite
Possible Duplicate:
Randomize a List<T> in C#
shuffle (rearrange randomly) a List<string>
Random plot algorithm
Hi I have the following list and I want to output the model into a list but do so randomly. I have seen a few examples but they seem to be really convuluted. I just want a simple way to do this?
List<Car> garage ----randomise------> List<string> models

List<Car> garage = new List<Car>();

garage.Add(new Car("Citroen", "AX"));
garage.Add(new Car("Peugeot", "205"));
garage.Add(new Car("Volkswagen", "Golf"));
garage.Add(new Car("BMW", "320"));
garage.Add(new Car("Mercedes", "CLK"));
garage.Add(new Car("Audi", "A4"));
garage.Add(new Car("Ford", "Fiesta"));
garage.Add(new Car("Mini", "Cooper"));
c# list random shuffle
shareimprove this question
asked Aug 29 ’12 at 14:16
Peter Crouch
18113

marked as duplicate by Tim Schmelter, sloth, L.B, John Arlen, Nasreddine Aug 29 ’12 at 14:26

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
possible duplicate of Randomize a List<T> in C# or Shuffle List<T> or … –  Tim Schmelter Aug 29 ’12 at 14:18

2 Answers

activeoldestvotes
up vote5down voteaccepted
I think all you want is this, it’s a simple way to do it;
Random rand = new Random();
var models = garage.OrderBy(c => rand.Next()).Select(c => c.Model).ToList();
//Model is assuming that’s the name of your property
Note : Random(), ironically, isn’t actually very random but fine for a quick simple solution. There are better algorithms out there to do this, here’s one to look at;
http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
shareimprove this answer

八月 22, 2015

Linux下修改文件创建时间(修改文件更改时间)

Filed under: linux — iseopad @ 7:27 下午

Linux下修改文件创建时间(修改文件更改时间)
进到要改的文件目录里

find . -name “*” -exec touch ‘{}’ \;

注:最后一定要加分号,{}外一定要加单引号,*表示所有的文件(. 代表当前目录下)

如果只修改单个文件

1.创建文件 touch tm //名字随便起

2.touch -r tm liunx-2.6.30.4(要改的文件名)//就是把Linux-2.6.30.4文件的时间改为tm文件的时间

如下是搜的

使用权限:所有使用者
使用方式:
touch [-acfm]
[-r reference-file] [–file=reference-file]
[-t MMDDhhmm[[CC]YY][.ss]]
[-d time] [–date=time] [–time={atime,access,use,mtime,modify}]
[–no-create] [–help] [–version]
file1 [file2 …]
说明:
touch 指令改变档案的时间记录。 ls -l 可以显示档案的时间记录。
参数:
a 改变档案的读取时间记录。
m 改变档案的修改时间记录。
c 假如目的档案不存在,不会建立新的档案。与 –no-create 的效果一样。
f 不使用,是为了与其他 unix 系统的相容性而保留。
r 使用参考档的时间记录,与 –file 的效果一样。
d 设定时间与日期,可以使用各种不同的格式。
t 设定档案的时间记录,格式与 date 指令相同。
–no-create 不会建立新档案。
–help 列出指令格式。
–version 列出版本讯息。

范例:
最简单的使用方式,将档案的时候记录改为现在的时间。若档案不存在,系统会建立一个新的档案。
touch file
touch file1 file2

将 file 的时间记录改为 5 月 6 日 18 点 3 分,公元两千年。
时间的格式可以参考 date 指令,至少需输入 MMDDHHmm ,就是月日时与分。
touch -c -t 05061803 file
touch -c -t 050618032000 file

将 file 的时间记录改变成与 referencefile 一样。
touch -r referencefile file将 file 的时间记录改成 5 月 6 日 18 点 3 分,公元两千年。
时间可以使用 am, pm 或是 24 小时的格式,日期可以使用其他格式如 6 May 2000。
====================================================================================
touch -d 和 date -s 的用法相同。如果没有指定日期,默认为系统日期
touch -d 18:03 file
touch -d “18:03” file
touch -d “6:03pm” file

如果没有指定时间,默认为 00:00:00
touch -d 20000506 file
touch -d “05/06/2000” file
touch -d “20000506” filetouch -d “6:03pm 05/06/2000” file
touch -d “20000506 18:03” file
touch -d “20000506 18:03:00” file

八月 12, 2015

c# MONGO驱动QUERY嵌套查询

Filed under: C#,MongoDB — iseopad @ 1:45 上午
具体操作方法如下:
{
"name" : "Thing1",
"children" : [
{ "name" : "C1", "value" : "A" },
{ "name" : "C2", "value" : "B" },
{ "name" : "C3", "value" : "C" }]
}, {
"name" : "Thing2",
"children" : [
{ "name" : "C3", "value" : "A" },
{ "name" : "C4", "value" : "B" },
{ "name" : "C5", "value" : "C" }]
}, {
"name": "Thing3",
"children": [
{ "name": "C5", "value": "A" },
{ "name": "C6", "value": "B" },
{ "name": "C7", "value": "C" }]
}
要进行查询

 

var query = things.Find(
Query.And(
Query.EQ("children.name", "C3"),
Query.EQ("children.value", "C")
));
children.name 是关键
var list = Searcher(MongoDBHelper.article_table, 2000,Query.EQ("Category.CategoryName",categoryName));

1.查询实体Model内 List<SonModel> sonModels内字段。

public SonModel GetSonModel(string modelId, string sonModelId)
{
var query = Query.And(
Query<Model>.EQ(m => m.Id, modelId),
Query<Model>.ElemMatch<SonModel>(m => m.SonModels , q => q.EQ(a => a.Id, sonModelId))
);
var result = this.GetCollection().Find(query).SetFields("sonmodel.$");
var model = result.SingleOrDefault();
if (model == null) return null;
var list = model.Folders.ToList();
return list.Count > 0 ? list[0] : null;
}

 

对应查询语法

{"_id" : ObjectId("53b294ecc10a332eb8f652af"),"SonModels" : { "$elemMatch" : { "Id" : "具体子编号" } } }

2.添加以及删除Model内 List<SonModel> sonModels内某条记录

/// <summary>
 /// 添加单条sonModel
 /// </summary>
 /// <param name="Number"></param>
 /// <param name="Pictures"></param>
 /// <returns></returns>
 public bool AddPic(string Number, PicDto Picture)
 {
 var query = Query<ADDto>.EQ(q => q.Number, Number);
 Picture.Id = ObjectId.GenerateNewId().ToString();
 var update = Update<ADDto>.AddToSet(q => q.Pictures, Picture);
 var result = this.GetCollection().Update(query, update);
 return result.Ok;
 }
 /// <summary>
 /// 删除单条SonModel
 /// </summary>
 /// <param name="Number"></param>
 /// <param name="PicId"></param>
 /// <returns></returns>
public bool DelPic(string Number, string PicId)
 {
 ObjectId oid = ObjectId.Empty;
 if (!ObjectId.TryParse(PicId, out oid)) return false;
 var query = Query<ADDto>.EQ(q => q.Number, Number);
 var update = Update<ADDto>.Pull(m => m.Pictures, q => q.EQ(c => c.Id, PicId));
 var result = this.GetCollection().Update(query, update);
 return result.Ok && result.DocumentsAffected > 0;
 }

其中update 对应的json语法

{ "$addToSet" : { "pictures" : { "_id" : ObjectId("5440caef2c9364045cde3a48"), "PictureUrl" : "/file/ad/543b386b87508b53006781db.jpg", "Name" : "阿水博客", "JumpUrl" : "Http;//ashui.net", "StartTime" : ISODate("2014-10-17T07:47:00Z"), "EndTime" : ISODate("2014-10-17T07:47:00Z"), "shopproductid" : null, "hits" : 232, "weight" : 0, "area" : [1, 2, 3] } } }

Powered by WordPress