X-Spirit的陋室铭

生活有的时候面临许多选择,这些选择让人困惑。 生活有的时候没有任何选择,这个时候让人压抑。 但无论生活有没有给你选择,你只能做一件事情: 排除困难,勇往直前!

2007年8月21日星期二

3.2 Comments注释

Comments in Java, like comments in most programming languages, do not show up in the executable program. Thus, you can add as many comments as needed without fear of bloating the code. Java has three ways of marking comments. The most common method is a //. You use this for a comment that will run from the // to the end of the line.

Java中的注释,和大多数编程语言中的注释一样,在可执行程序中不会显示。因此,你可以根据需要任意添加注释而不必担心导致代码膨胀。Java有三种注释方法。最普通的是用一个//符号。用这个符号来注释从//开始到一行结尾的内容。

System.out.println("We will not use 'Hello, World!'"); // is this too cute?

When longer comments are needed, you can mark each line with a //. Or you can use the /* and */ comment delimiters that let you block off a longer comment. This is shown in Example 3-1.

当需要更长的注释的时候,你可以用//来注释每一行。或者你也可以使用/*和*/这两个注释定界符来隔离一个较长的注释。如例子3-1所示

Example 3-1. FirstSample.java

1. /*

2. This is the first sample program in Core Java Chapter 3

3. Copyright (C) 1997 Cay Horstmann and Gary Cornell

4. */

5.

6. public class FirstSample

7. {

8.      public static void main(String[] args)

9.      {

10.            System.out.println("We will not use 'Hello, World!'");

11.     }

12. }

Finally, a third kind of comment can be used to generate documentation automatically. This comment uses a /** to start and a */ to end. For more on this type of comment and on automatic documentation generation, see Chapter 4.

最后,第三种注释用于自动生成文档。该注释以/**开始以*/结束。有关这种注释和自动生成文档的更多内容,请见第四章。

CAUTION注意

 

/* */ comments do not nest in Java. That is, you cannot deactivate code simply by surrounding it with /* and */ because the code that you want to deactivate might itself contain a */ delimiter.

/* */注释在Java中是不可嵌套的。也就是说,当你想要注释掉一段代码的时候,你不能简单的使用/*和*/,因为你想注释掉的代码可能就含有一个*/定界符。

3.1 A Simple Java Program一个简单Java程序

Let's look more closely at about the simplest Java program you can have—one that simply prints a message to the console window:

让我们更进一步来看一个最简单的向控制台窗口输出信息的Java程序。

 

public class FirstSample
{
      public static void main(String[] args)
      {
            System.out.println("We will not use 'Hello, World!'"); 
      }
}

It is worth spending all the time that you need to become comfortable with the framework of this sample; the pieces will recur in all applications. First and foremost, Java is case sensitive. If you made any mistakes in capitalization (such as typing Main instead of main), the program will not run.

你需要花费来熟悉这个例子的框架,这是值得的,因为这个框架将在所有应用程序中重现。首先,Java是大小写敏感的。如果你在大小写上犯了错误(例如把Main写成main),程序就不会运行。

Now let's look at this source code line by line. The keyword public is called an access modifier; these modifiers control the level of access other parts of a program have to this code. We have more to say about access modifiers in Chapter 5. The keyword class reminds you that everything in a Java program lives inside a class. Although we spend a lot more time on classes in the next chapter, for now think of a class as a container for the program logic that defines the behavior of an application. As mentioned in Chapter 1, classes are the building blocks with which all Java applications and applets are built. Everything in a Java program must be inside a class.

现在让我们一行行地来阅读这段代码。关键字public被称作访问修饰符;这些修饰符控制着这段代码对一个程序其他部分的访问权限。在第五章中我们将对访问修饰符做更多讨论。关键字class说明Java程序中的一切都是存在于类当中。尽管在下一章中我们将花费更多时间来讲述类,但现在我们不妨把类想像成一个承载描述应用行为的程序逻辑的容器。正如在第一章中提到的,类是一切Java应用程序和applet的构建模块。Java程序中的一切必须存在于类中。

Following the keyword class is the name of the class. The rules for class names in Java are quite generous. Names must begin with a letter, and after that, they can have any combination of letters and digits. The length is essentially unlimited. You cannot use a Java reserved word (such as public or class) for a class name. (See Appendix A for a list of reserved words.)

关键字class后面的就是类名。Java当中类的命名规则是相当宽松的。类名必须以字母开始,其后可以是任意字母和数字的组合。类名的长度基本上是无限的。你不可以使用Java保留字来作为类名。(保留字列表请参见附录A)

The standard naming convention (which we follow in the name FirstSample) is that class names are nouns that start with an uppercase letter. If a name consists of multiple words, use an initial uppercase letter in each of the words. (This use of uppercase letters in the middle of a word is sometimes called "camel case" or, self-referentially, "CamelCase.")

标准的命名规则是类名需是以一个大写字母开头的名词(如FirstSample这个名字中遵循的规则)。如果一个类名以多个单词组成,则每个单词使用首字母规则。(这种在一个词中间使用大写字母的用法有时又叫做“camel case”,或者形象的写作“CamelCase”)

You need to make the file name for the source code the same as the name of the public class, with the extension .java appended. Thus, you must store this code in a file called FirstSample.java. (Again, case is important—don't use firstsample.java.)

你需要使文件名和public类的名字相同,后面加上.java扩展名。因此,你需要将以上代码存储到一个文件名为FirstSample.java的文件中。(再次说明,大小写很重要,不要写成firstsimple.java)

If you have named the file correctly and not made any typos in the source code, then when you compile this source code, you end up with a file containing the bytecodes for this class. The Java compiler automatically names the bytecode file FirstSample.class and stores it in the same directory as the source file. Finally, launch the program by issuing the command:

如果你正确给文件命名并且没有在源代码中写入任何打字稿,那么当你编译这个源文件时,你将得到一个属于这个类的包含字节码的文件。Java编译器会自动把字节码文件命名为FirstSimple.class并将其存储在Java源文件的同一目录下。最后用如下命令来启动程序:

java FirstSample

(Remember to leave off the .class extension.) When the program executes, it simply displays the string We will not use 'Hello, World'! on the console.

(切记去掉.class扩展名)程序执行时,将在控制台简单输出一个字符串:We will not use ‘Hello,World’!

When you use

当你用

java ClassName

to run a compiled program, the Java virtual machine always starts execution with the code in the main method in the class you indicate. Thus, you must have a main method in the source file for your class for your code to execute. You can, of course, add your own methods to a class and call them from the main method. (We cover writing your own methods in the next chapter.)

来运行一个已经编译的程序时,Java虚拟机总是从你指定的类当中的main方法开始执行。当然你也可以在一个类中添加你自己的方法,并将之成为是main方法。(我们将在下一章中讨论编写自定义方法。)

NOTE

注意

 

According to the Java Language Specification, the main method must be declared public. (The Java Language Specification is the official document that describes the Java language. You can view or download it from http://java.sun.com/docs/books/jls.) However, several versions of the Java launcher were willing to execute Java programs even when the main method was not public. A programmer filed a bug report. To see it, visit the site http://bugs.sun.com/bugdatabase/index.jsp and enter the bug identification number 4252539. However, that bug was marked as "closed, will not be fixed." A Sun engineer added an explanation that the Java Virtual Machine Specification (at http://java.sun.com/docs/books/vmspec) does not mandate that main is public and that "fixing it will cause potential troubles." Fortunately, sanity finally prevailed. The Java launcher in JDK 1.4 and beyond enforces that the main method is public.

根据Java语言规范,main方法必须被声明为public。(Java语言规范是描述Java语言的官方文档。你可以从http://java.sun.com/docs/books/jls下载并查看)然而,有些版本的Java启动器在main方法不是public的时候也会执行Java程序。一个程序员提交了一个bug报告。请访问站点http://bugs.sun.com/bugdatabase/index.jsp 并输入bug标识号4252539来查看这个报告。然而这个bug被标记为“关闭,将不予修正”。一个Sun的工程师添加了一条解释,即Java虚拟机规范(http://java.sun.com/docs/books/vmspec)不要求main方法为public,并且“修正这个问题将导致潜在的麻烦.”幸运的是,心智健全最终获胜。JDK1.4及以上版本的Java启动器强制main方法为public。

There are a couple of interesting aspects about this story. On the one hand, it is frustrating to have quality assurance engineers, who are often overworked and not always experts in the fine points of Java, make questionable decisions about bug reports. On the other hand, it is remarkable that Sun puts the bug reports and their resolutions onto the Web, for anyone to scrutinize. The "bug parade" is a very useful resource for programmers. You can even "vote" for your favorite bug. Bugs with lots of votes have a high chance of being fixed in the next JDK release.

关于这个故事有两个有趣的方面。一方面,让那些经常过劳工作的且不专于Java的细琢的质量保证工程师对bug报告做出充满问题的决议是一件让人沮丧的事情。另一方面,值得注意的是Sun公司将bug报告和他们的决议放在网上,供大家细察。Bug检阅对程序员来说是一个很有用处的资源。你甚至可以为你最青睐的bug投票。那些票数最高的bug将会有很大的几率在下一版的JDK中被修复。

Notice the braces { } in the source code. In Java, as in C/C++, braces delineate the parts (usually called blocks) in your program. In Java, the code for any method must be started by an opening brace { and ended by a closing brace }.

注意程序中的括号{ }。和在C++中一样,在Java中,括号划分出程序中的各个部分(通常叫做程序块或代码块)。在Java中,任何方法的代码都必须以开括号{开始,以闭括号}结束。

Brace styles have inspired an inordinate amount of useless controversy. We use a style that lines up matching braces. Because whitespace is irrelevant to the Java compiler, you can use whatever brace style you like. We will have more to say about the use of braces when we talk about the various kinds of loops.

括号的使用风格引发了大量混乱的无用争论。我们使用一种风格将匹配括号排队。因为空格对Java编译器而言无关,你可以使用任何你喜欢的括号风格。我们将会在讲述各种循环的时候对括号的使用做更多的讨论。

For now, don't worry about the keywords static void—just think of them as part of what you need to get a Java program to compile. By the end of Chapter 4, you will understand this incantation completely. The point to remember for now is that every Java application must have a main method that is declared in the following way:

现在,暂时不关注关键字static void,就把他们看作是你要编译一个Java程序所必须的。在第四章最后,你将完全理解这个咒语。现在要记住的是每个Java应用程序必须有一个像下面这样定义的main方法:

public class ClassName
{
     public static void main(String[] args)
     {
           program statements
     }
}

C++ NOTE C++注释

 

As a C++ programmer, you know what a class is. Java classes are similar to C++ classes, but there are a few differences that can trap you. For example, in Java all functions are methods of some class. (The standard terminology refers to them as methods, not member functions.) Thus, in Java you must have a shell class for the main method. You may also be familiar with the idea of static member functions in C++. These are member functions defined inside a class that do not operate on objects. The main method in Java is always static. Finally, as in C/C++, the void keyword indicates that this method does not return a value. Unlike C/C++, the main method does not return an "exit code" to the operating system. If the main method exits normally, the Java program has the exit code 0, indicating successful completion. To terminate the program with a different exit code, use the System.exit method.

作为C++程序员,你知道类是什么。Java类和C++中的类相似。但是也有一些不同会使你陷入其中。例如,在Java中,所有的函数都是某个类的方法。(他们的标准术语叫做方法,而非成员函数。)因此,在Java中,你必须给main方法一个外壳类。你或许对C++中的静态成员函数也很熟悉。这是一些定义在类中但不对对象进行操作的成员函数。Java中的main方法总是静态的。最后,和在C++中一样,void关键字说明该方法不返回值。与C/C++不同的是,在C/C++中,main方法不会向操作系统返回一个“退出码”。而在Java中,如果main方法正常退出,Java程序将返回一个退出码0,以表示成功完成。要以不同的退出码终止程序,请使用System.exit()方法。

Next, turn your attention to this fragment.

下面,请注意以下这个片段:

{

     System.out.println("We will not use 'Hello, World!'");

}

Braces mark the beginning and end of the body of the method. This method has only one statement in it. As with most programming languages, you can think of Java statements as being the sentences of the language. In Java, every statement must end with a semicolon. In particular, carriage returns do not mark the end of a statement, so statements can span multiple lines if need be.

括号将方法体的开始和结束标记出来。方法中只有一个句子。和大多数编程语言一样,你可以认为Java语句就是一个语言的句子。在Java中,每个句子必须以分号结束。特别要指出的是,回车并不表示语句的结束,所以在需要的情况下语句可以跨越多行。

The body of the main method contains a statement that outputs a single line of text to the console.

main方法的方法体包含一条向控制台输出单行文本的语句。

Here, we are using the System.out object and calling its println method. Notice the periods used to invoke a method. Java uses the general syntax

这里,我们使用了System.out对象和它的println方法。注意用于调用方法的句点。Java使用一般语法:

object.method(parameters)

for its equivalent of function calls.

来进行函数调用。

In this case, we are calling the println method and passing it a string parameter. The method displays the string parameter on the console. It then terminates the output line so that each call to println displays its output on a new line. Notice that Java, like C/C++, uses double quotes to delimit strings. (You can find more information about strings later in this chapter.)

此时,我们调用println方法并传一个字符串参数给它。这个方法将该字符串参数显示在控制台中。之后就结束该输出行,因此,每个println调用都可以将其输出写入一个新行。注意到Java和C++一样,也使用双引号来划分字符串。(本章稍后将详细讨论字符串)

Methods in Java, like functions in any programming language, can use zero, one, or more parameters (some programmers call them arguments). Even if a method takes no parameters, you must still use empty parentheses. For example, a variant of the println method with no parameters just prints a blank line. You invoke it with the call

Java中的方法,像任何编程语言中的一样,可以使用零个一个或者更多参数(一些程序员习惯称之为变量)。即使有些方法没有参数,你也必须使用空圆括号。例如,不同的无参println方法只输出一个空行。你可以通过以下方法调用它:

System.out.println();

NOTE 注释

 

System.out also has a print method that doesn't add a new line character to the output. For example, System.out.print("Hello") prints "Hello" without a new line. The next output appears immediately after the "o".

System.out 也有一个不换行的print方法,例如System.out.print(“Hello”)就可以输出”Hello”而不换行。下个输出将紧跟在“o”的后面。

Core Java学习笔记声明

终于决定好好的学习Core Java了。

我的Core Java学习笔记基本上是自己把原文翻译一遍,然后对部分有价值的代码进行一些讨论。

学习笔记仅从最重要的部分开始。前两章暂不涉及。

原版书籍来源于Flyheart提供的电子书。本学习笔记连载的内容仅供自学之用,严禁用于任何商业用途,由此引起的任何后果本人概不负责。。。

由于本人水平有限,难免会有很多错误,希望大家多多捧场,多多指教。。

坚持

心情似乎总是随着外界的触动而不停变化。但是无论怎样,坚持才是最重要的。

在每一次感到自己卑微的时候,一定要想想自己为什么会卑微。自己有什么资本变得高尚了吗?

如果答案是否定的,就一定要坚持努力。

时间的付出其实并不重要,重要的是时间的利用。能够坚持不浪费一点一滴的时间,那么这些时间的付出就是值得的。

促成转变的机会尚未到来。

 

————坚持

2007年8月15日星期三

Google Earth上不可错过的15个坐标

从失事的船只到麦田圈不一而足,可能你还没有仔细的寻找过这些地标。不必遗憾错过了GoogleEarth上最有意思的部分之一,因为所有GoogleEarth里面最奇怪的地标都将一一的为您呈现。

当地人称它为荒地守护者。这是位于加拿大艾伯特的一处地理场景,从空中看起来就像是一个戴着美洲土著头巾和耳环的人头。当然,这个荒地守护者完全是大自然的鬼斧神工。GoogleEarth参数:50.010083,-110.113006

通过GoogleEarth寻找巨大和独一无二的东西,是发烧友们最热衷的事情之一。这个巨大的粉色兔子,位于意大利的PrataNevoso,是一群来自维也纳的艺术家建造起来的,据说长大200英尺。GoogleEarth参数:44.2442

毫无疑问,GoogleEarth是麦田圈最好的“朋友”。这些圈位于内华达州Beatty附近的沙漠之中。GoogleEarth参数:37.401437,-116.86773

奥普拉本人永远不可能这么大,幸好在亚利桑那有一个农民制造一个一个十英亩大的奥普拉头像迷宫,用以向这位脱口秀主持人致敬。在里面玩的人们可以告诉自己的朋友:我在奥普拉的大脑里面迷路了。GoogleEarth参数:33.225488,-111

如果你是一个情报工作者,那么GoogleEarth绝对能让大物体无所遁形。据说这是一个位于中印边境上的。控制的一片1.8平方英里土地。据说这个地方是用来训练坦克驾驶员的。GoogleEarth参数:38.265652,105.9517

如果你在GoogleEarth上待的时间比较长,你会沮丧的发现好多地方的地图分辨率都比较低。当然GoogleEarth也在逐步的更新高分辨率的图片,我们不妨先来看看澳大利亚Bondi海滩吧,在这里你甚至能看到比基尼上的标签

国家地理与GoogleEarth一道进行了一个名为AfricaMegaflyover的项目。国家地理杂志拍摄了超过500张高分辨率的图片,而GoogleEarth同样也能使用这些图片,比方说这一队在尼日利亚休整喝水的骆驼队

你住的地方停车困难么?在荷兰Westenbergstraat,似乎得把自己的汽车停在墙上…… GoogleEarth参数:52.069207,4.3139865

Google的卫星图片经常能够捕捉到地球居民的移动,例如这十个非洲大象。GoogleEarth参数:10.903497,19.93229

谁都希望能够乘坐飞机到处观光,GoogleEarth就提供了这样一个感受的机会。这张图片这是位于赞比亚和津巴布韦的维多利亚瀑布。GoogleEarth参数-17.925511,25.858223

GoogleEarth上没有广告,除非谁家的广告大到足以能够从太空中看清楚。比方说这个大大的福特标志,这是在密歇根州底特律附近发现的。GoogleEarth参数:42.302284,-83.231215

GoogleEarth有时能够拍到半空中飞行的飞机,这种照片已经发现了超过3300个,其中包括这张二战轰炸机飞过英格兰Huntingdon上空的瞬间。GoogleEarth参数:52.336392,-0.1953462

卫星的眼睛不单能够记录下人们的成就,当然也会记录下那些不成功的时间。一个例子就是上面这艘大船,翻了一半漂浮在伊拉克巴士拉附近的水面上。GoogleEarth参数:30.541634,47.825445

有些时候GoogleEarth能够很幸运的拍摄到正在发生的事件,比方说这张GoogleEarth拍摄下来的车祸现场,位置是在北达科他Bismarck郊外。  GoogleEarth参数:46.765669,-100.79274

有一些从GoogleEarth里面翻出来的照片相当的怪异,例如为什么巴黎附近的一个停车场上会有一个战斗机呢?GoogleEarth参数:48.825183,2.1985795

咱们中国的,更加神奇!
为人民服务 42°32"33.95"N, 94°19"36.80"E

排除万难去争取胜利 42°27"12.08"N, 94° 8"49.36"E

只争朝夕 42°39"33.30"N, 94°16"0.59"E

毛主席万万岁 42°39"18.85"N, 94°10"0.80"E

向斗争中学习 42°27"40.95"N, 94°14"36.80"E
祖国在我心中 39°41"43.47"N, 73°55"37.17"E
香格里拉-松赞林寺(经文) 27°52"5.10"N, 99°41"52.20"E
其中前五个在新疆哈密附近,“毛主席万万岁”在新疆喀什与吉尔吉斯斯坦接壤的边境线附近,最后一个在云南中甸市附近。
在Earth界面左上角的搜索框中录入坐标, 就可以直接看到了.
你会在 42°33'6.31"N, 94°13'6.95"E 找到柳树泉老机场,这是一个现在废弃的机场.
新的柳树泉机场位置为 43° 4'39.09"N, 92°48'29.61"E 。
卫星地图上出现的“毛主席万万岁”等5条标语信息,为原第八航校官兵在戈壁滩上创造的奇迹,这些环绕机场的“语录”地标,可以帮助飞行员保持空域位置,引导教、学员准确进出空域,地标所在区域的中心点,便是柳树泉机场。其中一角还有一条废弃跑道。因为柳树泉机场地处戈壁,附近没有明显的地物特征!飞机都是设备简单的初教机,导航设备简陋,所以就弄了语录地标。

2007年8月13日星期一

用Java向IPMSG发送消息(转)

飞鸽传书(IP Messenger,简为IPMsg)是一个小巧方便的即时通信软件,它适合用于局域网内甚至广域网间进行实时通信和文档共享。特别是在局域网内传送文件/文件夹的速度非常快!

  • IPMsg 是一款局域网内即时通信软件, 基于 TCP/IP(UDP).
  • 可运行于多种操作平台(Win/Mac/UNIX/Java), 并实现跨平台信息交流.
  • 不需要服务器支持.
  • 支持文件/文件夹的传送 (2.00版以上)
  • 通讯数据采用 RSA/Blofish 加密 (2.00版以上)
  • 十分小巧, 简单易用, 而且你可以完全免费使用它
  • 目前已有的版本包括: Win32, Win16, MacOS, MacOSX, X11, GTK, GNOME,Java 等, 并且公开源代码。

本文演示了如何使用Java的net包,向IPMSG客户端发送消息。
IPMSG Command 常量定义如下:

1 /*========== Constant Value ==========*/
 2 public static final long IPMSG_COMMASK = 0x000000ff;
 3 public static final long IPMSG_OPTMASK = 0xffffff00;
 4 public static final long IPMSG_NOOPERATION = 0x00000000;
 5 public static final long IPMSG_BR_ENTRY = 0x00000001;
 6 public static final long IPMSG_BR_EXIT = 0x00000002;
 7 public static final long IPMSG_ANSENTRY = 0x00000003;
 8 public static final long IPMSG_BR_ABSENCE = 0x00000004;
 9
10
11
12 public static final long IPMSG_BR_ISGETLIST = 0x00000018;
13 public static final long IPMSG_OKGETLIST = 0x00000015;
14 public static final long IPMSG_GETLIST = 0x00000016;
15 public static final long IPMSG_ANSLIST = 0x00000017;
16
17 public static final long IPMSG_SENDMSG = 0x00000020;
18 public static final long IPMSG_RECVMSG = 0x00000021;
19
20 public static final long IPMSG_READMSG = 0x00000030;
21 public static final long IPMSG_DELMSG = 0x00000031;
22
23 public static final long IPMSG_GETINFO = 0x00000040;
24 public static final long IPMSG_SENDINFO = 0x00000041;
25
26 // other opt
27 public static final long IPMSG_ABSENCEOPT = 0x00000100;
28 public static final long IPMSG_SERVEROPT = 0x00000200;
29 public static final long IPMSG_DIALUPOPT = 0x00010000;
30
31 // send opt
32 public static final long IPMSG_SENDCHECKOPT = 0x00000100;
33 public static final long IPMSG_SECRETOPT = 0x00000200;
34 public static final long IPMSG_BROADCASTOPT = 0x00000400;
35 public static final long IPMSG_MULTICASTOPT = 0x00000800;
36 public static final long IPMSG_NOPOPUPOPT = 0x00001000;
37 public static final long IPMSG_AUTORETOPT = 0x00002000;
38 public static final long IPMSG_RETRYOPT = 0x00004000;
39 public static final long IPMSG_PASSWORDOPT = 0x00008000;
40 public static final long IPMSG_NOLOGOPT = 0x00020000;
41 public static final long IPMSG_NEWMUTIOPT = 0x00040000;
42
43 public static final int MAXBUF = 8192;
44 /*========== end ==========*/

IPMSG收发数据包的格式(一行):

1 version(IPMSG版本):no(消息编号,可以用系统时间):user(发送消息的用户名):host(发送消息的主机名):command(上述 Command 常量,可以用 | 组合多个值):msg(消息内容)

示例(向IPMSG发送消息,需要先打开对方的IPMSG):

1 import java.io.IOException;
 2 import java.net.DatagramPacket;
 3 import java.net.DatagramSocket;
 4 import java.net.InetAddress;
 5 import java.net.SocketException;
 6 import java.net.UnknownHostException;
 7 import java.util.Date;
 8
 9 /**
10  * @author 乱 7 8 糟 http://blog.csdn.net/comstep
11 */
12 public class TestIPMSG
13 {
14 public static void main(String[] args)
15   {
16     DatagramSocket socket;
17     InetAddress address;
18
19 long IPMSG_SENDMSG = 0x00000020;
20
21     String SENDER = "乱 7 8 糟";
22     String HOST = "Localhost";
23     String MSG_CONTENT = "Hello World!";
24
25 try
26     {
27       socket = new DatagramSocket();
28       address = InetAddress.getByName("192.168.1.20");// 发送给消息的地址
29
30 /**
31        * IPMSG收发数据包的格式(一行):
32        * 
33        * version(IPMSG版本):no(消息编号,可以用系统时间):user(发送消息的用户名):
34        * host(发送消息的主机名):command(上述 Command 常量,可以用 | 组合多个值):
35        * msg(消息内容)
36        * 
37 */
38 byte[] buffer = ("1:" + new Date().getTime() + ":" + SENDER + ":" + HOST
39 + ":" + IPMSG_SENDMSG + ":" + MSG_CONTENT).getBytes();
40
41       DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
42           address, 2425);
43       socket.send(packet); // 发送报文
44
45       packet = new DatagramPacket(buffer, buffer.length);
46       socket.receive(packet);// 接收回应
47
48       String message = new String(packet.getData()); // 得到报文信息
49
50       System.out.println(message); // 显示对方返回的信息
51     }
52 catch (UnknownHostException e)
53     {
54       e.printStackTrace();
55     }
56 catch (SocketException e)
57     {
58       e.printStackTrace();
59     }
60
61 catch (IOException e)
62     {
63       e.printStackTrace();
64     }
65
66   }
67
68 }
69

你可以在 SourceForge 找到开源的 IP MSG for Java
http://blog.csdn.net/comstep

补记

这两天其实一直都想写点东西。但是苦于没有时间,于是思维的闪光一次一次被打入理性的冷宫。

上周,度过了一段紧张而又忙碌的时光。

周三的时候,忙碌了一天,下班就马上去参加公司安排的英语课了。讲课的是一个中国老师。去的人不多,我去的也不算早,但是课程还是没有开始。那个老师似乎在等待更多的人光临他的课程。。。。内容主要就是语法。一时间,我发现自己的英语竟然堕落到There be句型还会用错的地步了。。。一直满足于英语六级的我似乎还不知道什么叫做退步,可是当这个残忍的事实真的到来的时候,我发现自己对自己太有自信了。。。

周四的时候,本来已经累得筋疲力尽的自己还是硬着头皮去上了公司给安排的英语课。刚一进门,就发现那个老外已经拿着笔在白板上写写画画了。这个老师就和中国老师的风格不一样。讲课的时候,明确的提出The class will start on time。这个时候我突然想到了大学里的老师。很多老师都没有守时的规矩,学生不守时,老师也跟着往后拖。但是西方人的做法就是和我们不同,在他们的逻辑里,迟到是不值得照顾的。无论你有什么事,迟到就是迟到,是个不可弥补的失误。而在我们国人的眼里,有时候,一个小小的借口就成了原谅迟到的理由。。。

周五,真的是要挺不过去了。整个人像疯了一样,拼命的Ctrl+C、Ctrl+V来完成那些就剩一点点的任务。精神表面的轻松和坚持掩盖不住内心的疲惫,那种想要加速飞行却总是在山头徘徊的感觉真的比双脚踩在热锅上还让人难受。一直都相信只要狠一点点,就能促成飞跃的我,现在深刻感到自己那种勉强振作的逻辑的可笑!

周六,稀里糊涂的一天——一顿懒觉,一顿烧烤,一顿凉皮,一场电影。。。

周日,真的非常想去找同学聚聚,可是周日还是想多多休息。中午隔壁的室友和他老婆开始下厨做饭了。只剩下可怜的自己和同屋两个人。两个“单身汉”很无奈的跑出去觅食。最后竟然跑去逛西单了。想来觉得真不可思议,周日陪没有老婆的自己上街的居然是个老婆不在身边的准单身汉!唉。。。这就是月子啊。在超市,三说要买个饭盒,可是看看那唬人的价格,心都凉到嗓子眼儿了。我说:“三,你攒钱吧。”突然不自觉的笑了出来——天啊,我们潦倒到攒钱买饭盒的地步了。虽然心里也觉得挺辛酸的,但是三的那句话真的让我重新找回了振作的感觉:每个人在他事业起步的时候都会经历一个黑暗期……

疲惫、辛酸、彷徨,但是我始终站立着,大声呼喊着我的口号,只是周围的乌云仍然将它淹没……

When fate is playing with me, I still choose the right way and continue...

2007年8月12日星期日

JavaFX写的简易Rss阅读器

 

 

受http://www.oreillynet.com/onjava/blog/2007/05/javafx_first_steps_hello_onjav_1.html这篇文章的启发,加上想学习一下JavaFX,就在上面那篇文章的基础上,做了一个简易的RSS阅读器,其界面类似于Adobe Flex 2的一个demo:进入http://try.flex.org/index.cfm,找到Blog Reader的demo。

读取RSS feed并没有什么问题,使用rome:

java 代码

  1. package rssreader;   
  2. import com.sun.syndication.feed.synd.SyndEntry;   
  3. import com.sun.syndication.feed.synd.SyndFeed;   
  4. import com.sun.syndication.io.FeedException;   
  5. import com.sun.syndication.io.SyndFeedInput;   
  6. import com.sun.syndication.io.XmlReader;   
  7. import java.io.IOException;   
  8. import java.net.MalformedURLException;   
  9. import java.net.URL;   
  10. public class RssReader {   
  11. private URL url;   
  12. private Integer titleLength = 50;   
  13. public RssReader() {   
  14.     }   
  15. public SyndEntry[] load(String urlString) throws IllegalArgumentException, FeedException, IOException {   
  16. if (urlString != null && urlString != "") {   
  17. try {   
  18.                 url = new URL(urlString);   
  19.             } catch (MalformedURLException e) {   
  20.                 e.printStackTrace();   
  21. return null;   
  22.             }   
  23.         }   
  24. if (url == null) {   
  25. return null;   
  26.         }   
  27.         SyndFeedInput input = new SyndFeedInput();   
  28.         SyndFeed feed = input.build(new XmlReader(url));   
  29.         SyndEntry[] entries = (SyndEntry[]) feed.getEntries().toArray(new SyndEntry[0]);   
  30. for( SyndEntry entry : entries ) {   
  31.             entry.setTitle( entry.getTitle().length() > titleLength ? entry.getTitle().substring(0, titleLength - 3 ) + "..." : entry.getTitle() );   
  32.         }    
  33. return entries;   
  34.     }   
  35. }   

使用JavaFX构建UI:

JavaFX代码

  1. package rssreader;   
  2. import javafx.ui.*;   
  3. import javafx.ui.canvas.*;   
  4. import javax.swing.JComponent;   
  5. import com.sun.syndication.feed.synd.SyndEntry;   
  6. var reader:RssReader = READER;   
  7. class RssReaderModel {   
  8.     attribute rssUrl: String;   
  9.     attribute rssEntries: SyndEntry*;   
  10.     attribute rssContent: String?;   
  11.     attribute rssSelectedIndex: Integer;   
  12. }   
  13. var model = RssReaderModel {   
  14.     rssUrl: "http://woodstudio.javaeye.com/blog/rss_blog/alexcheng",   
  15. };   
  16. var panel = GroupPanel {   
  17. var row1 = Row {}   
  18. var row2 = Row {}   
  19. var col = Column {}   
  20.      rows: [row1, row2]   
  21.      columns: col   
  22.      content:    
  23.          [   
  24.             GroupPanel  {   
  25.                 row: row1   
  26.                 column: col   
  27. var row = Row {}   
  28. var labelCol =  new Column   
  29. var urlCol =  new Column   
  30. var butCol =  new Column   
  31.                 rows: row   
  32.                 columns: [labelCol, urlCol, butCol]   
  33.                 content:   
  34.                 [   
  35.                     SimpleLabel {   
  36.                         row: row   
  37.                         column: labelCol   
  38.                         text: "RSS URL:"
  39.                     },   
  40.                      TextField {   
  41.                         row: row   
  42.                         column: urlCol   
  43.                         columns: 60   
  44.                         value: bind model.rssUrl   
  45.                     },   
  46.                     Button {   
  47.                         row: row   
  48.                         column: butCol   
  49.                         text: "Get Entries"
  50.                         action: operation() {   
  51.                             model.rssEntries = reader.load(model.rssUrl);              
  52.                         }   
  53.                     }   
  54.                 ]   
  55.             },   
  56.             SplitPane   {   
  57.                 row: row2   
  58.                 column: col   
  59.                 orientation: HORIZONTAL   
  60.                 content:   
  61.                 [   
  62.                     SplitView  {   
  63.                         weight: 0.3   
  64.                         content:       
  65.                             Table {   
  66.                                     columns:   
  67.                                     [   
  68.                                         TableColumn {   
  69.                                             text: "Title"
  70.                                         },   
  71.                                         TableColumn {   
  72.                                             text: "Date"
  73.                                         },   
  74.                                     ]   
  75.                                     cells : bind foreach (entry in model.rssEntries)   
  76.                                             [   
  77.                                                 TableCell {   
  78.                                                     text: bind entry.title   
  79.                                                 },   
  80.                                                 TableCell {   
  81.                                                     text: bind entry.publishedDate.toLocaleString()   
  82.                                                 }   
  83.                                             ]   
  84.                                     selection: bind model.rssSelectedIndex   
  85.                                 }      
  86.                     },   
  87.                     SplitView  {   
  88.                         weight: 0.7   
  89.                         content:   
  90.                             EditorPane   {   
  91.                                 opaque: true
  92.                                 contentType: HTML   
  93.                                 editable: false
  94.                                 text: bind model.rssContent   
  95.                             }   
  96.                         }   
  97.                 ]   
  98.             }   
  99.          ]    
  100. };   
  101. trigger on (RssReaderModel.rssSelectedIndex = value) {   
  102. var desc = rssEntries[value].description.value;   
  103.     rssContent = " {desc} ";    
  104. }   
  105. MY_CONTAINER:JComponent.add(panel.getComponent());   

接着就是使用JSR223的scripting framework来执行:

java 代码

  1. package rssreader;   
  2. import javax.script.Bindings;   
  3. import javax.script.ScriptContext;   
  4. import javax.script.ScriptEngine;   
  5. import javax.script.ScriptEngineManager;   
  6. import javax.script.SimpleScriptContext;   
  7. import javax.swing.JFrame;   
  8. public class Main {   
  9. /**
  10.      * @param args
  11.      * @throws Exception
  12.      */
  13. public static void main(String[] args) throws Exception {   
  14.         RssReader reader = new RssReader();   
  15.         JFrame frame = new JFrame(   
  16. "RSS Reader implemented using JavaFX by alexcheng");   
  17.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
  18.         frame.setSize(800, 600);   
  19.         ClassLoader loader = Thread.currentThread().getContextClassLoader();   
  20.         ScriptEngineManager manager = new ScriptEngineManager(loader);   
  21.         ScriptEngine engine = manager.getEngineByExtension("fx");   
  22.         Bindings bindings = engine.createBindings();   
  23.         bindings.put("READER:rssreader.RssReader", reader);   
  24.         bindings.put("MY_CONTAINER:javax.swing.JComponent", frame   
  25.                 .getContentPane());   
  26.         ScriptContext context = new SimpleScriptContext();   
  27.         context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);   
  28.         context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);   
  29.         engine.setContext(context);   
  30.         String script = "import rssreader.FxMain;";   
  31.         engine.eval(script);   
  32.         frame.setVisible(true);   
  33.     }   
  34. }   

最后的界面如下:

javafxrssreader.JPG

 描述:
 JavaFX RSS Reader

 文件大小:
 74 KB

 看过的:
 文件被下载或查看 28 次

javafxrssreader.JPG

2007年8月2日星期四

手机黑盒测试方法详细介绍

1。 Release Test
  Purpose:
  测试手机的基本功能是否实现,是否有进一步测试的必要性
  Attention:
  Release Test的Test Case具有一定的典型性,主要是反映手机最基本功能的Test Case
  本类测试只需要依据Test Case进行测试,不需要进一步发挥
  如果有发现与Case无关的Error, 在测试通过后才可以填报Error Report
  此类测试有一门槛值,即Test Case的Pass率达到一定值(如95%)才能宣布版本发布成功,进入进一步的测试,否则此版本无效。
  除了门槛值外,如果重要功能模块的Test Case没通过,也会终止这个版本。
  2 System Test
  Full Round System Test
  Purpose
  对手机的所有功能进行全面的测试(所有语言包)
  由于Case不可能包含所有方面,所以测试时应适度发挥,尽力完成全面测试
  Common System Test (Medium or Minor)
  Attention:
  System Test一般分为两个部分,“跑Case”和Free Test。
  在测试初期,一般只需要按照Test Case测,把一些不可重现的Error都记录下来。同时遇到Test Case的问题或者不充分,应该立即解决(和Team Leader或者Special List讨论,补写Test Case)。在这一阶段结束后,一般要写一个Summary Report。把这一阶段的测试结果和遇到的问题、自己的见解都写在里面(当然是用English)。
  当所有Test Case都测完后,就进入Free Test期间。这里的Free Test具有明确的目的性和范围。一般来说,这段时间的Free Test只需要测自己负责的模块。而且Free Test还负责重现前期“跑Case”是遗留的不可重现的Error。
  3 Focus Test
  Purpose:
  集中于一个或几个点进行测试(同System Test)

  4 Stress Test
  Purpose:
  为了解决市场上发现的重大Error,而进行的有针对性的强度测试
  主要是利用边缘测试(临界测试)手段
  Attention:
  压力测试,顾名思义,是给手机施加一定压力,从而找出手机软件上的Error。一般来说,对手机施加的压力主要有:
  存储压力:由于手机采用的是栈式存储,所以当一个存储块满了之后,如果程序员不做相应处理或者处理不好的话,很容易造成其他存储区被擦除,从而在UI上出现问题(其他功能无法正常使用)。
  边界压力:边界一直是程序员最容易忽略的地方。
  响应能力压力:有时候某个操作可能处理的时间很长,在处理期间如果测试者再不断地进行其他操作的话,很容易出现问题。
  网络流量压力(如在接电话时进行短信服务)等等。
  在项目中,Stress Test有时也会用来重现不可重现的Error。
  由于有不少不可重现的Error是由于Memory Leak(内存泄漏)引起的,所以不停的重复同一个操作是重现一个不可重现的Error的一个好方法。
  5 Free Test

  Purpose:
  测试System Test中没有做完的不可重现Error
  寻找平时没有找到的忽略的Error
  Attention:
  在System Test阶段所用的Free Test具有明显的目的性和范围
  平时的Free Test从理论上应该对所测试的范围穷尽所有的测试方法。但是,这是不现实的。在实际项目中,主要有两个方面是Free Test所需要重视的。
  一是从UI Spec上找灵感。应为Test Case是依据UI Spec写的,所以从UI Spec上突破是一个行之有效的方法。UI Spec有一定的探索深度,加大探索深度,是一种突破的途径;另外同一个功能用其他不同的方法去实现,也是一种突破途径。
  二是多关注不同Feature之间的Interaction。这是手机软件相对比较容易出问题,而Test Case又很少能反映的地方。这是一个很大的Free Test空间。

2007年8月1日星期三

I will be

 

Mmm...

The world seems so cold
When I face so much all alone
A little scared to move on
And knowing how fast I have grown

And I wonder just where I fit in
Oh the vision of life in my head
Oh yes

I will be
Strong on my own
I will see through the rain
I will find my way
I will keep on
Traveling this road
Till I finally reach my dream
Till I'm living, and I'm breathing
My destiny, yeah yeah

I can't let go now
Even when darkness surrounds
But if I hold on, yeah
I will show the world
All the things that you never expected to see
From little old me, this pittsburgh girl

And I wonder just where my place is
Close my eyes and I remind myself this
Oh yeah yeah

I will be
Strong on my own
I will see through the rain
I will find my way
I will keep on
Traveling this road
Till I finally reach my dream
Till I'm living, and I'm breathing
My destiny, ohh

It comforts me
Ooh it keeps me
Alive each day of my life
Always guiding me
Providing me
With the hope I desperately need

Well I gotta believe
There's something out there meant for me
Oh I get on my knees
Praying I will receive
The courage to grow and the faith to know

That I will be
Strong on my own
I will see through the rain
I will find my way
I will keep on
Traveling this road
Till I finally reach my dream
Till I'm living, and I'm breathing
My destiny

 

每次听这首歌,感觉心中充满了力量!

生活中或许是冷酷的,充满了困惑和无奈。
然而,正在走投无路,迷失方向的时候,
心中一个坚强的声音不停的提醒自己:
我要自强不息,
我要拨开层层迷雾,
我要坚持走下去,
直到我实现我的梦想。

感谢Christina Aguilera的声音!