最新日志

发表于:2008-5-15 23:37:58
标签:中奖  

1

今天中了微软的百万英镑。

今天又是幸运的一天!

得了,啥也不说了。这年头啥都有。前些天刚刚举报了连续发来的FREE LOTTERY的
邮件垃圾邮件,这回又换花样了,居然说是MICROSOFT的,还整得一本正经的,一
点都没有在页面上修饰。看起来是个什么通知文章,结果看到后面才知道——

——我又中奖了!

幸好俺赶上了信息时代,网上搜什么都不愁,于是随便截了一段放到BAIDU上一摆,
这些来自UK的骗子,以为中国人就好骗吗?还是来自UK的中国骗子 or 中国骗子在UK骗
在中国的中国人?&……%%¥¥……(#¥&)%%……

Microsoft Corporations:
Customer Service
Wrights Lane,
Kensington London W85SP,
England UNITED KINGDOM
FILE REF: HL/5564/06/07/MICS
BATCH: MC11/834/5PDH /EU

OFFICIAL WINNING NOTIFICATION.

It is obvious that this notification will come to you as a surprise but please find time to read it carefully as we congratulate you over your success in the following official publication of results of the E-mail electronic online Sweepstakes organized by Microsoft, in conjunction with the foundation for the promotion of software products, (F.P.S.) held in London UK.
Where in your email address emerged as one of the online Winning emails in the 2nd category and therefore attracted a cash award of ?50.000.00 (eight Hundred and Fifty Thousand pounds sterling) Our winners are arranged into four categories with different winning prizes accordingly in each category. They are arranged in this format below:
These are your identification numbers:MCS-26799/097

CATEGORY NO.OF WINNERS WINNING PRIZES
1st. 2 ?950,000.00 pounds each
2nd. 8 ?850.000.00 pounds each
3rd. 13 ?650,000.00 pounds each
4th. 27 ?350,000.00 pounds each

We write to officially notify you of this award and to advise you to contact the processing office immediately upon receipt of this message for more information concerning the verification, processing and eventual payment of the above prize to you.
It is important to note that your award information was released with the following particulars attached to it.

(1) Award numbers: NL 56/7766
(2) Email ticket numbers: EAASL-130877
(3) Batch numbers: MC11/834/8PDH /EU
(4) The file reference numbers: HL/5574/41/07/MICS
{5} Serial Numbers: McST/006/NL46560

FOR VERIFICATION PURPOSE BE SURE TO INCLUDE:

(1) Your contact address.
(2) Your Tel/Fax numbers.
(3) Your Nationality/Country.
{4} Your Full Names.
(5) Occupation.
(6) Your Preffered Method Of Receiving Your Price(From Below)

MODE OF PRIZE REMITTANCE
(1)Cash Pick-Up (You coming Down to Uk Personally to Pick Your Price).
(2)Courier Delivery Of your Certified Winning Cheque Name and other
Winning Documents safely to you.

To file for your claim, Please contact your Validating Officer for VALIDATION of your winning . Winnings that are not validated within a specified time of winning notification are termed void and invalid. You are required to mention the above particulars of your
award in every correspondence to enable the Agent validate your winning.
CONTACT:
*******************************************************************
FOREIGN TRANSFER MANAGER
MR DAVE WILLIAMS
MICROSOFT SECURITY DEPARTMENT (UK).
E-mail:sir.williamsdave@hotmail.co.uk
mr.davewilliams@live.com

********************************************************************
The Microsoft Internet E-mail lottery Awards is sponsored by our CEO/Chairman, Bill Gates and a consortium of software promotion companies. The Intel Group, Toshiba, Dell Computers and other International Companies. The Microsoft internet E-mail draw is held periodically and is organized to encourage the use of the Internet and promote computer literacy worldwide.
Once again on behalf of all our staff,
CONGRATULATIONS!
Sincerely,
DR .ALAN STATHAM
M.S.PRO ZONAL COORDINATOR.

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 原创

评论(0) | 阅读(53)
发表于:2008-5-9 21:45:43
标签:TCP  网络通信  基于TCP  .net  framework  

1

转一篇TCP网络通信的好文——用C#实现基于TCP协议的网络通信


摘自CrossMan的专栏——用C#实现基于TCP协议的网络通讯

TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编 程。然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序。
  
  要进行基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分——主机名和端口,如www.yesky.com:80中,www.yesky.com就是主机名,80指主机的80端口,当然,主机名也可以用IP地址代替。当连接建立之后,就可以使用这个连接去发送和接收数据包,TCP协议的作用就是保证这些数据包能到达终点并且能按照正确的顺序组装起来。
  
  在.net framework的类库(Class Library)中,提供了两个用于TCP网络通讯的类,分别是TcpClient和TcpListener。由其英文意义显而易见,TcpClient 类是基于TCP协议的客户端类,而TcpListener是服务器端,监听(Listen)客户端传来的连接请求。TcpClient类通过TCP协议与 服务器进行通讯并获取信息,它的内部封装了一个Socket类的实例,这个Socket对象被用来使用TCP协议向服务器请求和获取数据。因为与远程主机 的交互是以数据流的形式出现的,所以传输的数据可以使用.net framework中流处理技术读写。在我们下边的例子中,你可以看到使用NetworkStream类操作数据流的方法。
  
  在下面的例子中,我们将建立一个时间服务器,包括服务器端程序和客户端程序。服务器端监听客户端的连接请求,建立连接以后向客户端发送当前的系统时间。
  
  先运行服务器端程序,下面截图显示了服务器端程序运行的状况:
  
  
  
  然后运行客户端程序,客户端首先发送连接请求到服务器端,服务器端回应后发送当前时间到客户端,这是客户端程序的截图:
  
  
  
  发送完成后,服务器端继续等待下一次连接:
  
  
  
  通过这个例子我们可以了解TcpClient类的基本用法,要使用这个类,必须使用System.Net.Socket命名空间,本例用到的三个命名空间如下:
  
  using System;
  using System.Net.Sockets;
  using System.Text;//从字节数组中获取字符串时使用该命名空间中的类
  
  首先讨论一下客户端程序,开始我们必须初始化一个TcpClient类的实例:
  
  TcpClient client = new TcpClient(hostName, portNum);
  
  然后使用TcpClient类的GetStream()方法获取数据流,并且用它初始化一个NetworkStream类的实例:
  
  NetworkStream ns = client.GetStream();
  
  注意,当使用主机名和端口号初始化TcpClient类的实例时,直到跟服务器建立了连接,这个实例才算真正建立,程序才能往下执行。如果因为网络不通,服务器不存在,服务器端口未开放等等原因而不能连接,程序将抛出异常并且中断执行。
  
  建立数据流之后,我们可以使用NetworkStream类的Read()方法从流中读取数据,使用Write()方法向流中写入数据。读取数据时, 首先应该建立一个缓冲区,具体的说,就是建立一个byte型的数组用来存放从流中读取的数据。Read()方法的原型描述如下:
  
  public override int Read(in byte[] buffer,int offset,int size)
  
  buffer是缓冲数组,offset是数据(字节流)在缓冲数组中存放的开始位置,size是读取的字节数目,返回值是读取的字节数。在本例中,简单地使用该方法来读取服务器反馈的信息:
  
  byte[] bytes = new byte[1024];//建立缓冲区
  int bytesRead = ns.Read(bytes, 0, bytes.Length);//读取字节流
  
  然后显示到屏幕上:
  
  Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead));
  
  最后不要忘记关闭连接:
  
  client.Close();
  
  下面是本例完整的程序清单:
  
  using System;
  using System.Net.Sockets;
  using System.Text;
  
  namespace TcpClientExample
  {
  public class TcpTimeClient
  {
  private const int portNum = 13;//服务器端口,可以随意修改
  private const string hostName = "127.0.0.1";//服务器地址,127.0.0.1指本机
  
  [STAThread]
  static void Main(string[] args)
  {
  try
  {
  Console.Write("Try to connect to "+hostName+":"+portNum.ToString()+"\r\n");
  TcpClient client = new TcpClient(hostName, portNum);
  NetworkStream ns = client.GetStream();
  byte[] bytes = new byte[1024];
  int bytesRead = ns.Read(bytes, 0, bytes.Length);
  
  Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead));
  
  client.Close();
  Console.ReadLine();//由于是控制台程序,故为了清楚的看到结果,可以加上这句
  
  }
  catch (Exception e)
  {
  Console.WriteLine(e.ToString());
  }
  }
  }
  }
  
  上面这个例子清晰地演示了客户端程序的编写要点,下面我们讨论一下如何建立服务器程序。这个例子将使用TcpListener类,在13号端口监听,一旦有客户端连接,将立即向客户端发送当前服务器的时间信息。
  
  TcpListener的关键在于AcceptTcpClient()方法,该方法将检测端口是否有未处理的连接请求,如果有未处理的连接请求,该方 法将使服务器同客户端建立连接,并且返回一个TcpClient对象,通过这个对象的GetStream方法建立同客户端通讯的数据流。事实上, TcpListener类还提供一个更为灵活的方法AcceptSocket(),当然灵活的代价是复杂,对于比较简单的程序, AcceptTcpClient()已经足够用了。此外,TcpListener类提供Start()方法开始监听,提供Stop()方法停止监听。
  
  首先我们使用端口初始化一个TcpListener实例,并且开始在13端口监听:
  
  private const int portNum = 13;
  TcpListener listener = new TcpListener(portNum);
  listener.Start();//开始监听
  
  如果有未处理的连接请求,使用AcceptTcpClient方法进行处理,并且获取数据流:
  
  TcpClient client = listener.AcceptTcpClient();
  NetworkStream ns = client.GetStream();
  
  然后,获取本机时间,并保存在字节数组中,使用NetworkStream.Write()方法写入数据流,然后客户端就可以通过Read()方法从数据流中获取这段信息:
  
  byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
  ns.Write(byteTime, 0, byteTime.Length);
  ns.Close();//不要忘记关闭数据流和连接
  client.Close();
  
  服务器端程序完整的程序清单如下:
  
  using System;
  using System.Net.Sockets;
  using System.Text;
  
  
  namespace TimeServer
  {
  class TimeServer
  {
  private const int portNum = 13;
  
  [STAThread]
  static void Main(string[] args)
  {
  bool done = false;
  TcpListener listener = new TcpListener(portNum);
  listener.Start();
  while (!done)
  {
  Console.Write("Waiting for connection...");
  TcpClient client = listener.AcceptTcpClient();
  
  Console.WriteLine("Connection accepted.");
  NetworkStream ns = client.GetStream();
  
  byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
  
  try
  {
  ns.Write(byteTime, 0, byteTime.Length);
  ns.Close();
  client.Close();
  }
  catch (Exception e)
  {
  Console.WriteLine(e.ToString());
  }
  }
  
  listener.Stop();
  }
  }
  }
  
  把上面两段程序分别编译运行,OK,我们已经用C#实现了基于TCP协议的网络通讯,怎么样?很简单吧!
  
  使用上面介绍的基本方法,我们可以很容易的编写出一些很有用的程序,如FTP,电子邮件收发,点对点即时通讯等等,你甚至可以自己编制一个QQ来!

点击此处查看原文 >>

系统分类: 通信网络   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(95)
发表于:2008-5-9 12:55:52
标签:活动建议  

3

给EDN活动提点建议

 
    提点建议,EDN的活动我很支持,对大家有帮助,对EDN有好处,是个共赢互利的事情。

    只是觉得有一点,关于转帖的问题。无论在博客上还是论坛上,随意转 别人的贴而不写出处已经称为中国网络心照不宣的事情,长期,人们也将其看成很自然的事情。我不知道外国网络是什么样子,所以无权评价。但就事论事地说,我 心理觉得不太好受。

    开始我也是那种随便转帖的人,而且从没想过这样做有什么不妥。直到当我自己也写一些文章,经验,等等,并且想到网络这么大,我的一些很 有价值的文章,经验肯定早晚会被别人转去的。于是心里有一点点自私,毕竟是我花时间和精力做的东西,仅被别人Ctrl+C一下就成了别人的?而且还不注明 出处。又想,如果他注明了出处,我心里就平衡不少了。这时我意识到这样做是很不负责任的表现,是对别人劳动的不尊重。

    己所不欲,勿施于人。从此, 我转帖时开始注意到要加上出处。可能我有点自私,可能很多人很无私奉献。但是如果大家没有这样的习惯,就像盗版软件在中国的严重,已经影响到中国软件业的 发展一样,转帖不注出处也会影响到网络上好资料,有价值的文章的出现。其实很多有经验的人都会有些这样的心理吧,一些对自己很有价值,自己花了精力创作的东西不轻 易放在网上的。一般如果是可以卖的产品,都会拿出一小部分做一下宣传,然后在淘宝上卖云云。

    因此建议EDN在搞一些活动时能够加上一条规则:转帖要注明出处,否则无权参赛。不尊重别人劳动的人怎么能得到别人的尊重呢?以帮助大家养成尊重别人劳动的好习惯。否则,你这样转帖,会导致下一批网友也这样转帖;你不尊重别人,同时培养了一批不尊重你的人,结果是互相不尊重。一切交流,都是互相的。我们是希望生活在一个互相尊重的环境中呢,还是希望生活在一个互相不尊重的环境中呢?

    当然我们可以选择生活在互相不尊重的环境中,并且现在基本上就是这样的环境。我们也可以生活的很好,只要我们有足够的耐受力,能够看开这些,能够不把它当回事,能够接收这种不尊重,并且把它看成自己很大方,免费提供很多好东西,同时别人也要大方的对自己。这同样也是一种生活环境。可能我们生活在这种环境中久了,也就没感觉了。我们中华民族的确是耐受力很强的民族,对环境有着很强的适应力,这是优点,同时也是我们的缺点。

    希望能够引起大家的思考,对我们民族文化的一点思考。

    再次希望EDN再次搞活动时能够关注关于转帖不注出处的意见。我知道有很多人会反对我的观点。我们可以观点不同,可以意见达不成一致,但是我们可以交换各自的观点,让各自互相理解对方的意思。

——————————————————————————————————

    由此想到了一些相关的问题,再说说毕业论文。我不知道中国大学有多少学生是全部摘抄别人的,有多少是80%的摘抄,有多少是50%的摘抄,有多少20%的摘抄,又有多少完全是原创的。我只从郑强教授的演讲得知日本的大学的毕业论文(无论什么论文),好像没有“查资料”的概念,他们都是根据自己的研究得到的成果所做的论文。(当然学术理论是世界共享的)

    还听说(忘了在哪里听的了)澳大利亚的大学对论文抄袭现象管的非常严,说如果摘抄别人的字句超过两句话(还是多少个字,具体我忘了)就要注明出处;并且如果超过5句话(具体数字忘了)或一个段落的摘抄别人的文章就算是论文抄袭,直接没有成绩。

    当然现在我做不到毕业论文完全绝对的原创,还是要参考一些书籍和资料,我的习惯也不是一下就能改变的。但,就个人来讲,还是从一点一滴做起,从改变自己做起。我们管不了别人,只能管好自己,一辈子能学会管好自己就已经是件很不容易的事情了。

    君子穷则独善其身,达则兼济天下。修身齐家平天下,能做到第一样就很成功。孔子70才达到随心所欲不逾矩,长江后浪推前浪,相信自己的努力能够超过他老人家。

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 原创

评论(11) | 阅读(382)
发表于:2008-5-8 11:24:31
标签:UDP  TCP  

1

UDP协议简介


转自http://www.gfdtu.cn/gfdtu_Article_12523.html技术文章

    UDP协议是英文UserDatagramProtocol的缩写,即用户数据报协议,主要用来支持那些需要在计算机之间传输数据的网络应用。包括网络视 频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议 所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。

  与我们所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。

  UDP协议的主要作用是将网络数据流量压缩成数据报的形式。一个典型的数据报就是一个二进制数据的传输单位。每一个数据报的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

UDP报头

UDP报头由4个域组成,其中每个域各占用2个字节,具体如下:

源端口号

目标端口号

数据报长度

校验值

   UDP协议使用端口号为不同的应用保留其各自的数据传输通道。UDP和TCP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。 数据发送一方(可以是客户端或服务器端)将UDP数据报通过源端口发送出去,而数据接收一方则通过目标端口接收数据。有的网络应用只能使用预先为其预留或 注册的静态端口;而另外一些网络应用则可以使用未被注册的动态端口。因为UDP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。一 般来说,大于49151的端口号都代表动态端口。

  数据报的长度是指包括报头和数据部分在内的总的字节数。因为报头的长度是固定的,所 以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为 65535字节。不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。

  UDP协议使用报头中的校验值来保证数据的 安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音 等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。

UDPvs.TCP

   UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时, 会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。

  与TCP不同,UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。

  相对于TCP协议,UDP协议的另外一个不同之处在于如何接收突法性的多个数据报。不同于TCP,UDP并不能确保数据的发送和接收顺序。例如,一个位于客户端的应用程序向服务器发出了以下4个数据报

D1

D22

D333

D4444

但是UDP有可能按照以下顺序将所接收的数据提交到服务端的应用:

D333

D1

D4444

D22

事实上,UDP协议的这种乱序性基本上很少出现,通常只会在网络非常拥挤的情况下才有可能发生。

UDP协议的应用

   也许有的读者会问,既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可能会变得非常有用。因为 UDP具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影 响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。

  关于 UDP协议的最早规范是RFC768,1980年发布。尽管时间已经很长,但是UDP协议仍然继续在主流应用中发挥着作用。包括视频电话会议系统在内的许 多应用都证明了UDP协议的存在价值。因为相对于可靠性来说,这些应用更加注重实际性能,所以为了获得更好的使用效果(例如,更高的画面帧刷新速率)往往 可以牺牲一定的可靠性(例如,会面质量)。这就是UDP和TCP两种协议的权衡之处。根据不同的环境和特点,两种传输协议都将在今
后的网络世界中发挥更加 重要的作用

点击此处查看原文 >>

系统分类: 通信网络   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(162)
发表于:2008-4-30 9:58:47
标签:datasheet  w3100a  

1

总结点经验,有的datasheet有bug,有些细节还不阐明。

最近在用W3100A做毕业设计,发现它的例程中有些地方(关于一个缓冲区寄存器指针的用法)总是看不通,参考它的datasheet也没有仔细说 明这里。到他们公司网站上提问,也没人回答,看了一下它们关于这款芯片的问答,都是在2003年以前的。而且他们公司也不宣传这款芯片了。便想,是不是这 款芯片有缺陷,有了取代品了?就看看他们正在宣传的W3150A和W5100,最后,终于在W3150A的datasheet中看到了这个缓冲区寄存器指 针的用法。经验便是,不能在一棵树上吊死。

我可是对于这个bug研究了好多天啊。浪费了不少时间。

点击此处查看原文 >>

系统分类: 通信网络   |    用户分类:    |    来源: 原创

评论(1) | 阅读(238)
发表于:2008-4-30 9:35:43
标签:W3100A  TCP芯片  

1

终于明白了W3100A的BUF计算方法,居然在W3150A芯片的datasheet中看到的

终于明白了它的BUF计算方法,居然是在W3150A芯片的datasheet中看到的。看来W3100A的datasheet的确很多bug。

哈哈,长经验,不能一棵树上吊死!它不更新W3100A的datasheet定是有原因的,W3150A取代它了!


点击看大图
点击看大图
点击看大图
通过这几张图就看明白了,它是用什么方法用BUF的,也明白了为什么它的BUF_PR寄存器要4个八位组的。

点击此处查看原文 >>

系统分类: 通信网络   |    用户分类:    |    来源: 原创

评论(0) | 阅读(111)
发表于:2008-4-30 9:33:05
标签:W3100A  TCP芯片  

1

这时才知道W3100A的SHADOW_REG是怎么用的。


例程中的一个函数,由此我明白了它的shadow register是怎么用的。说实在的,它这款芯片真的不怎么地,datasheet中的bug多不说,想shadow register这中用法还是头一次见到,这种用法感觉很不可理喻。

怪不得他们公司都不宣传W3100A了,也不更新它的datasheet了。可能没人用这款老芯片了。新款芯片取代了老的。

u_int select(SOCKET s, u_char func)
{
    u_int val;
    un_l2cval rd_ptr, wr_ptr, ack_ptr;
    u_char k;

    EX0 = 0;
    switch (func) {
    case SEL_CONTROL :                   // socket status information
        val = IndirectReadByte(SOCK_STATUS(s));
        break;

    case SEL_SEND :                // Calculate send free buffer size
        k = IndirectReadByte(SHADOW_TXWR_PTR(s)); // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(TX_WR_PTR(s),(u_char*)&wr_ptr,4);

        if( (IndirectReadByte(OPT_PROTOCOL(s)) & 0x07) != SOCK_STREAM)
        {
            k = IndirectReadByte(SHADOW_TXRD_PTR(s));  // Shadow Register needs to be read before reading buffer register
            wait_1us(2);
            IndirectReadBuf(TX_RD_PTR(s),(u_char*)&ack_ptr,4);
        }
        else
        {
            k = IndirectReadByte(SHADOW_TXACK_PTR(s));  // Shadow Register needs to be read before reading buffer register
            wait_1us(2);
            IndirectReadBuf(TX_ACK_PTR(s),(u_char*)&ack_ptr,4);
        }

        if (wr_ptr.lVal >= ack_ptr.lVal) val = SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal);
        else val = SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal);
        break;
    case SEL_RECV :                  // Calculate received data size    
        k = IndirectReadByte(SHADOW_RXWR_PTR(s));    // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(RX_WR_PTR(s),(u_char*)&wr_ptr,4);

        k = IndirectReadByte(SHADOW_RXRD_PTR(s));    // Shadow Register needs to be read before reading buffer register
        wait_1us(2);
        IndirectReadBuf(RX_RD_PTR(s),(u_char*)&rd_ptr,4);

        if (wr_ptr.lVal == rd_ptr.lVal){ val = 0;}
        else if (wr_ptr.lVal > rd_ptr.lVal) val = wr_ptr.lVal - rd_ptr.lVal;
        else val = 0 - rd_ptr.lVal + wr_ptr.lVal;
        
#ifdef DEBUG
        PutString("wr_ptr.lVal = ");PutLTOA(wr_ptr.lVal);PutString(" : rd_ptr.lVal = ");PutLTOA(rd_ptr.lVal);PutString(" : size = ");PutITOA(val);PutStringLn("");
#endif       
        break;
    default :
        val = -1;
        break;
    }
    EX0 = 1;
    return    ( val );
}
 

这里的计算buffer大小还不太明白。


点击此处查看原文 >>

系统分类: 通信网络   |    用户分类:    |    来源: 原创

评论(0) | 阅读(104)
发表于:2008-4-12 0:35:54
标签:自然  随想  

1

人类——>探索

宇宙的神奇在于她诞生了地球,
地球的神奇在于她诞生了生命,
生命的神奇在于她诞生了人类,
人类的神奇在于她试图寻找这一切神奇的缘由,在于她探索自己的来源,自然的奥秘。

我不禁感叹自然的伟大,生命的神奇。

遥想,自从那一天,自然力的作用使得部分无忧无虑生活在森林中的猿不得不接受下地行走的事实后,他们便开启了一扇崭新的命运之门,即将面临与留在森林中的那些曾经的伙伴们不同的生命历程。他们不会想到,他们的子孙也会因为这一偶然事件而改变命运。

他们生活的比以前艰辛,因为他们必须面对从未面对的环境。告别了热爱的森林,他们灵活的手臂在草原不再具有优势,相反,那些依靠发达的四肢,尖牙历爪的家伙们是这里的统治者。他们没有大象一样庞大的身躯、厚实的皮囊;他们没有羚羊那样的犄角;他们也没有野猪的刚刺;他们……他们是这个大草原中的新学员。为了生存,他们生活在一起,一起寻找灌木的果实,可食的菜叶,……一切可食的东西,都成为他们猎取的对象。当猎食者来袭,他们得想办法摆脱,使大多数人逃脱……他们渐渐学会了与他们斗争,学会了使用武器,制造火种,使用工具……

一年一年,一代一代,最初从森林走出的人类后代,已经适应了地上的生活。而且生活的很好,他们栖居在山洞中,留有随时可用的火种,拥有自己的领地,靠耕种生活。偶尔,也会出去打打猎,换换口味。那也是乐观的猜测,事实也许会更辛苦些,而且也会随时有灭顶之灾——谁知道老天什么时候不高兴呢?

他们继续努力,努力不让老天脸色决定自己的命运。迁徙,选择更好的地方,选择自己决定命运……

一些人迁到了北方,那里土地肥沃,水源丰富。一些人向东,那里拥有温暖的气候。一代接一代,迁徙着的人类,在这个星球的各个角落撒下了自己的种子。

尽管生存很现实,生存时时都给人类敲着警钟。人们仍不希望平时无事可做,他们想出各种自娱自乐的办法:在墙壁上画画:今天,大家设了一个大陷阱,一起捕获了一头大野猪……

当东方人画着画,记录着他们历史之时,生活在北方的兄弟们在祷告着神灵的护佑。他们已经拥有比较稳定的生活,作为回报,他们感谢神灵的恩赐。他们援引了某些圣人在岩石上记录的符号,并把他们赋予神圣的力量……

不知多少代人,当年兄弟的后代早已变化的面貌全非,是环境改变了人?他们用不同的语言说话,用不同的文字书写,用不同的脑细胞思考。

但,相同的是,他们都在与生存做斗争,与自然做斗争,渐渐的,他们又都开始思考每一事件的缘由。东方的兄弟们采用他们的图画文字作为这最初探索的工具,西方的兄弟们采用他们的符号来探索。他们对这个世界有不同的认识,对不同事物有自己的解释,然而,很多事情,无论采用哪种方式,都可以理解,都讲得通。只是方式不同,当然头脑中所呈现的景象也不同。

或许,可以说他们生活在两个世界里,但是现实世界是只有一个的。当他们再次碰面,同样在这个世界,也许某个角落,他们思维的碰撞,也即这两种环境造就的两种思维的碰撞,会不会是大自然碰撞与融合的一个映像?


点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 原创

评论(1) | 阅读(167)
发表于:2008-4-10 9:55:12
标签:volatile  

1

两篇关于volatine的文章,很透彻【转】

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如

操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行

优化,从而可以提供对特殊地址的稳定访问。

使用该关键字的例子如下:

int volatile nVint;

当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指

令刚刚从该处读取过数据。而且读取的数据立刻被保存。

例如:

volatile int i="10";
int a = i;
。。。//其他代码,并未明确告诉编译器,对i进行过操作
int b = i;

volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的

汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间

的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果

i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问

注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编

代码,测试有无volatile关键字,对程序最终代码的影响:

首先用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:

#include <stdio.h>
void main()
{
 int i="10";
 int a = i;

 printf("i= %d\n",a);
        //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
 __asm {
  mov         dword ptr [ebp-4], 20h
 }

 int b = i;
 printf("i= %d\n",b);
}

然后,在调试版本模式运行程序,输出结果如下:
i = 10
i = 32

然后,在release版本模式运行程序,输出结果如下:
i = 10
i = 10

输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。

下面,我们把 i的声明加上volatile关键字,看看有什么变化:


#include <stdio.h>
void main()
{
 volatile int i="10";
 int a = i;

 printf("i= %d\n",a);
 __asm {
  mov         dword ptr [ebp-4], 20h
 }

 int b = i;
 printf("i= %d\n",b);
}

分别在调试版本和release版本运行程序,输出都是:
i = 10
i = 32

这说明这个关键字发挥了它的作用!

iwaswzq 于2004/12/4/16:15

 

第二篇、转自 gaoteng1984的专栏http://blog.csdn.net/gaoteng1984/archive/2007/07/27/1711924.aspx

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值(From Memory),而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
3); 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

 

 

第三篇、ANSI C之关键词volatile

转自wendy_welcom的专栏http://blog.csdn.net/wendy_welcom/archive/2008/02/20/2109616.aspx

这几天,趁着下一个项目还没来的间隙,决定好好补一补C语言, 看见《 C Primer Plus 》书里的这段话,书是跟同事借的,因为知道我这“聪明的”脑袋基本记不住事儿,只好记录下来等忘了时再看;又因为很懒,所以干脆把记下来的东西,贴在博客上凑数,这样子博客上就又多了一篇读书笔记了,嘿嘿。 这里要成我的学习笔记本了,咯咯。
ANSI C新规定了三个限定词,volatile,restrict,const。
限定词volatile告诉编译器该变量除了可被程序改变以外还可以被其他代理改变。典型地,它被用于硬件地址和与其他并行运行的程序共享的数据。例如,一个地址中可能保存着当前的时钟时间。不管程序做些什么,该地址的值都会随着时间而改变。另一种情况是一个地址被用来接收来自其他计算机的信息。
volatile int locl;    /*locl是一个易变的位置   */
volatile int *ploc; /*ploc指向一个易变的位置 */
您可能以为volatile是一个有趣的外行的概念,但您也可能奇怪为什么ANSI觉得有必要把volatile作为一个关键字。原因是它可以方便编译器优化。例如,假定有如下代码:
val1 = x;
       /* 一些不使用x的代码x */
val2 = x;
    一个聪明的(优化的)编译器可能注意到您两次使用了x, 而没有改变它的值。编译器将把x临时存储在一个寄存器中。接着,当val2需要x时,可以通过从寄存器而非初始的内存位置中读取该值以节省时间。这个过程被称为缓存(caching)。通常,缓存是一个好的优化方式,但如果在两个语句间其他代理改变了x的话就不是这样了。如果没有规定volatile关键字,编译器将无从得知这种改变是否可能发生。因此,为了安全起见,编译器不使用缓存。那是在ANSI以前的情形。然而现在,如果在声明中没有使用关键字volatile,编译器就可以假定一个值在使用过程中没有被修改,它就可以试着优化代码。
   所以,我可以得出这样结论:如果使用了volatile,不存而是从初始的内存中该值; 如果没有使用volatile, 就利用存的方法从寄存器中取。   (这段话不是书上的,是俺个人的读书心得,呵呵。)
    一个值可以同时是vonst和volatile。例如,硬件时钟一般设定为不能由程序改变,这一点使他成为const; 但它被程序以外的代理改变,这使它成为volatile的。只需在声明中同时使用这两个限定词,如下所示,顺序并不重要:
volatile const int ioc;
const volatile int *ploc;

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(188)
发表于:2008-4-9 21:48:00
标签:太极  生活  

3

终于找到白鹤亮翅的感觉了,真通畅!

今天晚上终于找到白鹤亮翅的感觉了!

而且正、反旋圈也找到感觉了!

做出来真舒展,真通畅!

太极拳讲的: 劲力其根在脚,发于腿,主宰于腰,形于手指.

这不是一年两年能领悟的,需要长期的练习和灵感。

终于发现我在一点一点领悟,需要坚持,持久的练习。
每天都会有新的发现,新的领悟。

白鹤亮翅很舒展!

点击此处查看原文 >>

系统分类: 生活点滴   |    用户分类:    |    来源: 原创

评论(7) | 阅读(185)
总共 , 当前 /,234下一页