日记

  1. 最新日记

  2. 日记

    1. 我的日记
    2. 我的文章
    3. 网络文摘
 

最新日记

Java Socket编程
2010-03-24 23:00

    事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作。Socket就是其中之一,对于Java而言,这些Api存在与java.net 这个包里面,因此只要导入这个包就可以准备网络编程了。
    网络编程的基本模型就是客户机到服务器模型,简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数据的通讯就可以了,这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端,基于这个简单的模型,就可以进入网络编程啦。
    Java对这个模型的支持有很多种Api,而这里我只想介绍有关Socket的编程接口,对于Java而言已经简化了Socket的编程接口。首先我们来讨论有关提供固定位置的服务方是如何建立的。Java提供了ServerSocket来对其进行支持.事实上当你创建该类的一个实力对象并提供一个端口资源你就建立了一个固定位置可以让其他计算机来访问你,ServerSocket server=new ServerSocket(8080);这里稍微要注意的是端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从 0~65535之间的,前1024个端口已经被Tcp/Ip 作为保留端口,因此你所分配的端口只能是1024个之后的。好了,我们有了固定位置.现在所需要的就是一根连接线了.该连接线由客户方首先提出要求。因此 Java同样提供了一个Socket对象来对其进行支持,只要客户方创建一个Socket的实例对象进行支持就可以了。
    Socket client=newSocket(InetAddress.getLocalHost(),8080);客户机必须知道有关服务器的IP地址,对于着一点Java也提供了一个相关的类InetAddress 该对象的实例必须通过它的静态方法来提供,它的静态方法主要提供了得到本机IP 和通过名字或IP直接得到InetAddress的方法。
    上面的方法基本可以建立一条连线让两台计算机相互交流了,可是数据是如何传输的呢?事实上I/O操作总是和网络编程息息相关的。因为底层的网络是继续数据的,除非远程调用,处理问题的核心在执行上,否则数据的交互还是依赖于IO操作的,所以你也必须导入java.io这个包.java的IO操作也不复杂,它提供了针对于字节流和Unicode的读者和写者,然后也提供了一个缓冲用于数据的读写。
    BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
   PrintWriter out=new PrintWriter(server.getOutputStream());
    上面两句就是建立缓冲并把原始的字节流转变为Unicode可以操作,而原始的字节流来源于Socket的两个方法,getInputStream()和getOutputStream()方,分别用来得到输入和输出,那么现在有了基本的模型和基本的操作工具,我们可以做一个简单的Socket例程了.
服务方:
    import java.io.*;
  import java.net.*;
  public class MyServer {
  public static void main(String[] args) throws IOException{
  ServerSocket server=new ServerSocket(8080);
   Socket client=server.accept();
  BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
   PrintWriter out=new PrintWriter(client.getOutputStream());
   while(true){
   String message=in.readLine();
    System.out.println(message);
   out.println("I has receive....");
    out.flush();
   if(str.equals("stop"))
    break;
  }
   client.close();
  }
  }
    这个程序的主要目的在于服务器不断接收客户机所写入的信息只到,客户机发送"End"字符串就退出程序,并且服务器也会做出"Receive" 为回应,告知客户机已接收到消息。
客户机代码:
    import java.net.*;
  import java.io.*;
    public class Client{
  static Socket server;
   public static void main(String[] args)throws Exception{
   server=new Socket(InetAddress.getLocalHost(),8080);
  BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
  PrintWriter out=new PrintWriter(server.getOutputStream());
   BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
   while(true){
   String message=br.readLine();
    out.println(message);
   out.flush();
   if(str.equals("stop")){
    break;
   }
   System.out.println(in.readLine());
  }
  server.close();
  }
  }
  客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识。
    这个程序只是简单的两台计算机之间的通讯,如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的。那么多个客户端如何实现呢?
    其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身,而服务器通过accept方法就是同意和客户建立通讯.这样当客户建立Socket的同时。服务器也会使用这一根连线来先后通讯,那么既然如此只要我们存在多条连线就可以了。那么我们的程序可以变为如下:
服务器:
    import java.io.*;
  import java.net.*;

  public class MyServer {
  public static void main(String[] args) throws IOException{
  ServerSocket server=new ServerSocket(8080);
  while(true){
   Socket client=server.accept();
   BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
   PrintWriter out=new PrintWriter(client.getOutputStream());
   while(true){
     String str=in.readLine();
    System.out.println(str);
     out.println("has receive....");
    out.flush();
     if(str.equals("end"))
     break;
   }
   client.close();
  }
  }
  }

  这里仅仅只是加了一个外层的While循环,这个循环的目的就是当一个客户进来就为它分配一个Socket直到这个客户完成一次和服务器的交互,这里也就是接受到客户的"End"消息.那么现在就实现了多客户之间的交互了。但是.问题又来了,这样做虽然解决了多客户,可是是排队执行的。也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互,无法做到同时服务,那么要如何才能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了。所以线程是最好的解决方案。
    那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系。然后由线程来执行刚才的操作,要创建线程要么直接继承Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执行线程就必须重写run方法,而run方法所做的事情就是刚才单线程版本main所做的事情,因此我们的程序变成了这样:
这里只是服务端程序,客户端还原来一样.
    import java.net.*;
  import java.io.*;

  public class MultiUser extends Thread{
  private Socket client;

  public MultiUser(Socket c){
  this.client=c;
  }

  public void run(){
  try{
   BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
    PrintWriter out=new PrintWriter(client.getOutputStream());
    //Mutil User but can't parallel
   while(true){
    String str=in.readLine();
    System.out.println(str);
     out.println("has receive....");
    out.flush();
     if(str.equals("end"))
     break;
   }
   client.close();
  }catch(IOException ex){
  }finally{
  }
  }

  public static void main(String[] args)throws IOException{
   ServerSocket server=new ServerSocket(8080);
  while(true){
   //transfer location change Single User or Multi User
  MultiUser mu=new MultiUser(server.accept());
  mu.start();
  }
  }
  }

  我的类直接从Thread类继承了下来.并且通过构造函数传递引用和客户Socket建立了联系,这样每个线程就有了。一个通讯管道.同样我们可以填写run方法,把之前的操作交给线程来完成,这样多客户并行的Socket就建立起来了。

BASE64编码代码
2009-10-11 17:39

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import sun.misc.BASE64Encoder;

public class Base64 {

/**
* 作者:夏砜
*/
public static void main(String[] args)throws IOException{
BASE64Encoder encoder=new BASE64Encoder();
System.out.println("please input user name:");
String username=new BufferedReader(new InputStreamReader(System.in)).readLine();
System.out.println(encoder.encode(username.getBytes()));
System.out.println("please input password:");
String password=new BufferedReader(new InputStreamReader(System.in)).readLine();
System.out.println(encoder.encode(password.getBytes()));


}

}

  BASE64的编码含义就是将我们日常32bit转化成在计算机上运用的8bit的代码,要是您想对BASE64做更近一步的了解,可以在网上查看相关资料.这篇文章是与上面《手工发送一封e-mail》相结合的,如果您要是想知道我写的是什么,请先浏览上一篇文章。

    分别在sina和sohu建立一个油箱帐号,邮件服务器(接受和发送的作用) 客户端连接到sina.sina转发邮件(利用到smtp协议),客户端再连接到sohu的pop3服务器(利用到pop3协议)

先连接sina的smtp邮件服务器:
telnet smtp.sina.com 25  (用户名和密码都会被base64处理,就是将你所需要的用户名以及密    码转换成BASE64的编码.)
ehlo itcase_test(跟sina的smtp服务器打个招呼)
250-mai5-202.sinamail.sina.com.cn
250-8BITMIME
250-SIZE 31457280
250-AUTH PLAIN LOGIN
250 AUTH=PLAIN LOGIN(stmp服务器支持两种认证方式PLAIN and LOGIN)
Auth login  (我告诉服务器我的认证方式为auth login)
334 VXNlcm5hbWU6 (服务器要求用户输入用BASE64编过码的用户名)
aXRjYXNlX3Rlc3Q=  (此处输入用BASE64编码过的用户名)
334 UGFzc3dvcmQ6
MTIzNDU2              (此处输入用BSAE64编码过的密码)
235 #2.0.0 OK Authenticated
mail from:<itcast_test@sina.com>  (发信人)
250  sender <itcast_test@sina.com> ok
Rcpt to:<itcast_test@sohu.com> (接受人)
Data                        (开始写有关信息)
345 go ahead
From:<liliw@sohu.com>   
Subject:haha         (正文标题)(其他参数to ,date 等)
Test!!!            (正文内容)
.               (正文内容以句号完成)
250 ok:Message 73453646 accepted
Qiut                  (退出服务器)
221 mail5-203.sinamail.sina.com.cn

接下来我们将登陆到sohu的邮件服务器上面来去这封邮件 
Telnet pop3.sohu.com 110  (连接sohu的pop3服务器)
+OK stmp.suhu.com pop3 Server Ready    (这是与sohu的pop3服务器建立连接的标志)
User itcasr_test            (此时的用户名不需要利用BSAE64编码)
+OK Password required for "itcast_test@sohu.com
Pass 123456                (输入油箱的密码)
+OK user "itcast_test@sohu.com"has 1 message<s>.
Stat            (利用这样的命令来查看油箱的状态)
+OK 1 1099      (其中的"1"指的是邮件数,"1099"指的是邮件所占的空间大小)
List        (来查看每封邮件的情况)
+OK 1 Message <1099 octets>
1 1099
.
List 1    (来查看某封邮件占用空间的情况)
+OK 1 1099 <1>
Retr 1  (来返回某封邮件的内容) 

Dele 1
+OK Message 1 deleted. (此时做的是一个删除的标记,只有在退出服务器时,我们所标记删除的邮件才会被删除)
Stat
+OK 0 0
Rset                  (如果在我们标记了某封邮件删除时,但是没有退出,可以利用此命      令恢复这封被删除的邮件)
+OK 1 message <1099 octets>stat
+OK 1 1099
Quit       
+OK smtp.sohu.com POP3 Server signed off.

STMP协议
  全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与STMP服务器之间,以及两台SMTP服务器之间的通讯规则.
POP3协议
  全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则.
IMAP协议
  全称为Internet Message Access Protocol(Internet 消息访问协议),它是对POP3协议的种扩展,定义了邮件客户端软件与IMAP服务器的通讯规则.


利用本机冒充服务器向sina发送一封邮件

如果是利用像outlook的客户端来访问sina的smtp服务器时,是需要利用到密码来认证的.
如果是利用像sohu这样的邮件服务器给sina的smtp服务器发送一封邮件是不需要知道sina的smtp服务器的用户名和密码的.

首先要知道 sina的smtp服务器的名称:
  在"运行"状态下  >nslookup
                  DNS request timed out.
                      Timeout was 2 seconds.
                  ***Can't find server name for address 211.82.96.2:timed out
                  Default Server: dns1.bistu.edu.cn
                  Address:211.82.96.1
                  >set type=mx
                  >sina.com  (用来解析sina邮件服务器的smtp服务器的地址和名称)
                  Server:dns1.bistuedu.cn
                  Address:211.82.96.1
                 
Non-authoritative answer:  (sina.com    MX preference=10,mail exchanger=freemx1.sinamail.sina.com.cn
Sina.com    MX preference=10,mail exchanger=fressmx2.sinamail.sina.com.cn
Sine.com    MX preference=10,mail exchanger=freemx3.sinamail.sina.com.cn
Sina.com    nameserver= ns3.sina.com.cn
Sina.com    nameserver=ns1.sina.com,.cn
Sina.com    nameserver=ns2.sina.com.cn
Ns1.sina.com.cn  internet address=202.106.184.166
Ns2.sina.com.cn  internet address=61.172.201.254
Ns3.sina.com.cn  internet address=202.108.44.55
(在用户访问它的smtp服务器的时候,它会将它所拥有的所有服务器告诉给你,但是访问者只能利用到第一个服务器,其他的用户在访问时候,服务器将循环的将自己的服务器分配出去,这样就使得服务器负载均衡)
>exit
Telnet freemx1.sinamail.sina.com.cn 25 (此时所telnet的是MX1号服务器) 
200 irja2-159.sinamail.sina.com.cn ESMTP
Ehlo 123.118.6.116  (本机地址)
250-irja2-159.sinamail.sina.com.cn
250-8BITMIME
250 SIZE 31457280    (此时就不需要认证)
Mail from:<itcast_test@sohu.com>
250 sender <itcast_test@sohu.com>
Rcpt to:<itcast_test@sina.com>250 recipient<<itcast_test@sina.com> ok
Data
354 go ahead
Subject: xixi
Test2!!!!!
.
250 ok:Message 98846597 accepted
Qiut
211 irja2-159.sinamail.sina.com.cn



  本实验的目的是让读者对邮件的发送和接受有一个较深层次的了解,可以让读者利用命令符提示界面发送一封简单邮件。在实验中遇到了很多的问题,有的邮件服务器对用户是相对关闭的,所以用户在利用他们的邮件服务器发送邮件时,将会遇到邮件服务器无法开启的现象。sina邮件服务器是相对开放的,可以利用.我也不在这里多说了,要是你有什么问题,可以跟我留言。以后将陆续提供利用JAVA编写邮件发送程序(JavaMail),谢谢您的关注!!

Rip的等价负载均衡
2009-10-11 17:24


本实验是利用以太网口和串口进行配置实验,配置完成后R1分别从以太网口和串口学习到到达R3的路径而且度量值都相等,所以R1就将两者全部添加到路由表上.分别在路由器上将RIP协议配置好后,利用"show ip route "来查看路由器所学习到的路由信息.
  我们打开R1的icmp 互联网控制信息协议(debug ip icmp)。再去ping R3会看到它发送数据的方式是先走以太网,再走串行线。 可利用ICMP协议查看R3上数据传送所走的路径,此时看到R3的应答信息,同样也是一条路径发送一次.
  还可以用traceroute 路由跟踪去ping 一下R3,此时也如此。这就是负载均衡。
  实验总结:在一个路由表中有多条路径到达同一个地方,这时它采取等价负载均衡的方法去发送数据。这样减轻路由的发送功能。注:要看到它的发送过程必需打开icmp。

RIP的单播更新
2009-10-11 17:23


如图所示:实验中所利用的实验原理是将R2与R1,R3的路由更新的联系断开,从而达到只有R1与R3进行路由更新(单播更新),不能与R2进行路由更新.这样就减少了网络中的路由更新的广播,减轻网络负载.
  本实验是利用访问端口来进行配置的,所以在实验中没有利用到串口.并利用到交换机将R!中的F0/0的端口与R2和R3进行连接.
    在配置R1的时,在"R1(configure-router)#"的模式下进行配置,利用"network A.B.C.D"告之路由器自己所连接的相邻网段,"passive-interface f0/0"来对端口F0/0进行限制,一旦限制了它的接口它只会接收数据而不会发送数据."neighbour A.B.C.D"来定义它的邻居,它只会发送数据给指定的neighbour.

CCNA找工作指南
2009-07-21 12:56

作者:网络雄猫 QQ:7553969


CCNA,作为思科认证系列里面最为初级的认证,同MCSE一样,在整个IT认证历史上产生了巨大的,深远的,不可磨灭的影响,可以说至少有两代人受它的熏陶,影响,通过获得这个证书走上了自己的理想的职业道路,在全球有数百万的人获得了这个证书。并且,由于它的进入门槛较低,思科在网路行业不可动摇的优势,所以将继续成为那些想进入网络行业人士的必经之门。可以这样说:“IT认证恒久远,CCNA永流传”


当然,CCNA是肯定不如CCNP,CCSP,CCIP,CCIE好的。可是,每个人都受着各种客观环境因素的制约,有些事情只能想想,“雄关漫道真如铁,而今迈步从头越”,思科认证由于金钱,时间花费巨大,比如,CCIE,很多人目前来讲,那都是可望而不可及的东西。所以,只能咬紧牙关,从头做起。本人2000年考思科认证的时候,CCIE就像是神仙姐姐,看一眼都目眩,但是培训费用达到了10万,还不包含考试费,你还别嫌贵,还不打折。当然,那个时候,IE的月薪至少2万以上,可是,有什么办法呢,有那个贼心,也有那个贼胆,没有那个贼钱啊。想卖房子,房子不是我的,想卖身,又卖不出去。怎么办,当然只有CCNA了。本人闭关苦练3个月,考过CCNA后,立马跳槽。可以说,没有当时的CCNA就没有我今天的CCIE,就没有《思科-网络帝国》这本书的出版,就没有www.cc-ie.com了。


我们本人要对CCNA有个正确的认识,就是CCNA还是一个初级认证,它不代表技术的颠峰,当然更不能指望它养你一辈子。但是,我们还要*它不但要解决温饱问题,还有解决发展问题。这就是说,我们要*它找个不错的工作。


这个世界是相对的,没有一种东西可以占据绝对的优势,它有优点必有缺点。两件事物对抗的基本原理就是以己之长,攻彼之短。当然还要防止别人“以彼之道,还施彼身”,下面,我们就要对CCNA说长道短。我们找工作,其实就是把自己卖出去的过程,卖东西的精髓就是让客户感到你的东西是能满足客户的需求,并且物美价廉。


1, 技 术

CCNA是网络技术工程师,并且完全有能力完成一个小型或者中型网络的设计,安装调试和维护。CCNA的课程覆盖面已经相当全面,从局域网,到广域网,从NAT到OSPF,从ISDN到帧中继,基本都有涉及。而这些东西都是日常企业组网时最常用的技术。这些小到中型的网络,99%用到的都是CCNA的东西。但是,CCNA毕竟是思科公司的认证,在产品和对产品的软件操作方面,具有思科公司本身的特色,俗话说,“林子大了,什么鸟都有!”这公司小了,什么设备都有,作为一个CCNA,恐怕还要面对一些不知名品牌的乱七八糟的设备,这个也没有关系。技术基本上都是标准的,或者说这些产品所支持的技术,思科都支持,思科支持的技术,这些产品并不一定支持。这就好比,经常开奔驰,偶尔开开奥拓,虽然有些不习惯,可是开起走,肯定时没有问题的,并且很快就会适应。


2, 名 气

CCNA在业界的名气还是不小的,很多人都知道思科的认证,CCIE是熊掌,CCNA怎么也是熊腿啊。CCNA相对于CCIE的名气是小了一点,可是,相对于那些没有认证的人来说,还是具有相当大的优势。我们都说大学本科现在不顶用了,可是,你别忘记,还有那么多人专科毕业,职业技术学校毕业,还有那么多人高中毕业。所以,你的比较优势还是比较明显的。不管怎么说,证书还是管用的。因为面试的一面之词,或者一纸笔试,的确不能以一管窥全豹。所以,证书还是从侧面衡量了你以前的努力和深厚的基础。不过,由于一些人的投机取巧心里(找人替考,背bible),还有一些不法机构的不负责任(替考,卖题目),这些证书是真正的‘paper’,仅是一张纸而已,不代表任何实际意义。不可否认,这在以前,很多人对情况并不了结的情况下,确实是效果立竿见影,可是现在再做这种事情,就是拔苗助长,害己害人。就是因为,思科认证的这种龙蛇混杂状态,导致了一些用人单位,对CCNA产生了片面的怀疑态度。其实,CCNA本身并没有什么过错,它依旧是一个非常优秀的网络技术基础认证。错在有些人霸王硬上弓,强*了CCNA。所以,用人单位,要对持有思科认证者给予一定的考察,那些滥竽充数者自然会露出马脚。如果仅凭一纸证书,找工作无门的话,那么CCNA泛滥之势就可以被控制住。CCNA之“王子归来”就可能会重演。注意,本找工作指南只适用于那些货真价实得CCNA。


注:

不过,有些公司同样犯有叶公好龙的错误,我们知道,他们希望自己公司的员工拥有证书,这样对外宣传,投标的时候,增加公司的实力,伟岸公司的形象。形式大于内在,这是整个中华民族历史遗留下来的顽症,不过,随着群众思想的发展,企业的管理理念的进步,这些错误念头早晚会被摒弃,在着一个知本主义时代,知识最终会为各种要素之首。记住,沧海横流,不变的唯有自己的本事。


3.价 格

价格是永恒的竞争因素。每个公司经营更要考虑成本问题,每个公司不可能充满博士,或者CCIE。这个还不只是价格问题,还有更深层次的管理问题,5只龙,不一定斗得过两只龙,两只虎和一只鹰。而这样下来,成本还会低很多。现在干什么都讲团队作战,既然是团队,就应该有梯度。一般一个公司的技术团队,应该包括一个经验丰富,善于处理疑难杂症的高手,这个可以由CCIE担任,还要几个能独立撰写大的方案,独立解决一些客户问题的专家,这个以是CCNP,或者CCIE来担任,但是需要更多的是可以冲锋在第一线,可以写一些小的方案,也可以解决一般客户问题的工程师,其实,客户碰到的问题,一般都是一些常识问题。这个工作就可以由CCNA来完成。CCNA的相对便宜的价格,让一些公司可以多个雇佣。一个CCIE的工资等得上3个或者4个CCNA的。就是从公司的传统的面子角度来说吧,一个公司人数众多,怎么也比孤零零的几个人立在哪里强吧!所以,CCNA比CCIE容易卖多了。



4.合 适

将来与你共度一生,并且过得非常幸福的人,不是最漂亮的人,不是最能干的人,不是最贤惠的人,而是最适合你的人。同样,一个公司招人,不是招技术最好的人,也不是招学历最高的人,更不是招品德最好的人。而是招最适合那个职位的人。对于很多公司的很多职位来讲,CCNA就是最好的选择。


5.风物长宜放眼量

现在的情况是大部分CCNA都很郁闷,他们找不到工作,或者说是合适的工作。考过了CCNA反而觉得人矮了一头,就象到大城市来的农民不好意思说自己是村长似的。我们必须承认这个社会是世俗的,清高的人到世俗的社会里只有死路一条。很多人对真正的情况并不了解。他们对这些方面的知识是不完备的。他们认为CCNA都是“纸”一张,或者听说很多CCIE都是“纸”,何况CCNA乎,这虽不合逻辑,但是却是事实。这对很多CCNA来说,是个障碍,也是机遇。障碍就是按照他们的逻辑,CCIE是纸,那么CCNA就成空气了。机遇就是你只要能说明那不成逻辑,只是事实(有的CCIE是纸,有的CCNA也是纸),并且是没有任何必然联系的事实,你就获得了机会,甚至是干掉和你一样竞争的“纸”CCIE,他们这种不盲目崇拜IE的认识,其实是给了CCNA莫大的机会。任何证书对人的证明都存在于表面,任何真正的证明最终还是*人的本身。庆幸的是现在没有人*一纸证书就对人顶礼膜拜,任何一家公司都要经过测试才能做出决定。只要你能坐在面试官前,任何人的机会都是平等的。任何昂贵的证书只是让你离面试官更近一些,但是却永远不能贴近他的心灵。


CCNA必须一边哭泣,一边奋斗!你们的环境是相对恶劣,但是起因是不想只是呆在原地,等待人人都能看见的太阳,而是为了能看到美丽的极光,而不得不去穿越暴风雪。


最后,我把我喜欢的两句话送给大家:


生存环境只不过是对我们产生一种间接影响,每一个人的心灵也并不全合乎他周围的环境,每一个人都活在她自己的心灵世界中。至于所处的世界如何,主要在我们以什么样的方式来看待之。

--叔本华


真正的光明绝不是永没有黑暗,只是永不被黑暗所掩蔽罢了;

真正的英雄绝不是永没有卑下的情操,只是永不被卑下的情操所屈服罢了。

JDBC连接
2009-07-19 13:07

package org.sx.com;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class CJdbcTest {

public static void main(String[] args) {

String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@10.1.1.252:1521:orcl";
                String sql="select PROID,PRONAME from T_PROPERTIES";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;


try {
                        // 1. 加裁驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(strUrl, "SXS", "SXS");
// 3. 建立会话
stmt=conn.createStatement();
// 4. 获取结果集(执行)
rs=stmt.executeQuery(sql);

while(rs.next()){
// 循环取得结果集
System.out.println("==========姓名1:"+rs.getString(2)+"\t 姓名2="+rs.getString("PRONAME"));
}

}catch (Exception e) {
e.printStackTrace();

} finally{

try {
if(null!=rs){
  rs.close();
}
if(null!=stmt){
stmt.close();
}
if(null!=conn){
  conn.close();
}

} catch (SQLException e) {

e.printStackTrace();
}
}
}

}
  注意:本实验只是较简单的利用JAVA编程与数据库进行连接,并且对数据库中相关的表进行操作。
  详细说明:本次实验我利用的是ORCLE数据库,在与数据库建立连接的时要添加相关的驱动String driver = "oracle.jdbc.driver.OracleDriver"和Class.forName(driver)语句来完成,先前还要在数据库上面建立你所需要的表,上面的实验中我所建立的是T_PROPERTIES表,我对其表在与数据库建立连接后的操作是:将表中数据的ID和NAME打印出来"select PROID,PRONAME from T_PROPERTIES"和System.out.println("==========姓名1:"+rs.getString(2)+"\t 姓名2="+rs.getString("PRONAME"))语句来完成。在获取连接时conn = DriverManager.getConnection(strUrl, "SXS", "SXS")在括号中的strUrl为String strUrl = "jdbc:oracle:thin:@10.1.1.252:1521:orcl"中内容(是服务器的IP地址,服务器的端口号和服务器的名称),在后面的两个"SXS"分别是:进入数据库时你所设立的帐号以及密码。建立会话的过程就是一个执行“预编译”的过程stmt=conn.createStatement()。最后通过rs=stmt.executeQuery(sql)语句对你所设定的操作进行执行。最后要注意语句执行完后一定要对数据库进行关闭(finally后部分)。
  此实验只共参考,详细的内容可以查看相应的书籍。因为此实验要在有数据库和服务器的情况下才能成功,所以准备工作相当的复杂,我认为只要弄清楚其中的原理就可以了。以后我会再对JAVABEAN和SURLET进行讲解。

    下面我们给出一个用Socket实现的客户和服务器交互的典型的C/S结构的演示程序,读者通过仔细阅读该程序,会对前面所讨论的各个概念有更深刻的认识。程序的意义请参考注释。
1.客户端程序 
 import java.io.*; 
 import java.net.*;  
public class TalkClient {   
 public static void main(String args[]) {  
    try{     
   Socket socket=new Socket("127.0.0.1",4700);        
 //向本机的4700端口发出客户请求   
   BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));   
  //由系统标准输入设备构造BufferedReader对象        PrintWriter os=new PrintWriter(socket.getOutputStream());        //由Socket对象得到输出流,并构造PrintWriter对象        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));     
 //由Socket对象得到输入流,并构造相应的BufferedReader对象        String readline;  
 readline=sin.readLine();
//从系统标准输入读入一字符串   
  while(!readline.equals("bye")){     
    //若从标准输入读入的字符串为 "bye"则停止循环              os.println(readline);     
   //将从系统标准输入读入的字符串输出到Server              os.flush();      
   //刷新输出流,使Server马上收到该字符串                  System.out.println("Client:"+readline);      
    //在系统标准输出上打印读入的字符串                    System.out.println("Server:"+is.readLine());           //从Server读入一字符串,并打印到标准输出上              readline=sin.readLine();
        //从系统标准输入读入一字符串   
     }//继续循环     
   os.close();//关闭Socket输出流  
   is.close();//关闭Socket输入流     
   socket.close();//关闭Socket   
   }catch(Exception e) {   
     System.out.println("Error"+e);//出错,则打印出错信息                            }  
      }
}


2.服务器端程序 
 import java.io.*; 
 import java.net.*; 
 import java.applet.Applet; 
 public class TalkServer{  
  public static void main(String args[]) {  
    try{    
    ServerSocket server=null;       
             try{    
       server=new ServerSocket(4700);    
     //创建一个ServerSocket在端口4700监听客户请求    
              }catch(Exception e) {                        System.out.println("can not listen to:"+e);               //出错,打印出错信息        }
          Socket socket=null;   
     try{     
         socket=server.accept();     
      //使用accept()阻塞等待客户请求,有客户              //请求到来则产生一个Socket对象,并继续执行    
    }catch(Exception e) {       
   System.out.println("Error."+e);     
      //出错,打印出错信息     
                       }   
     String line;     
   BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));    
     //由Socket对象得到输入流,并构造相应的BufferedReader对象        PrintWriter os=newPrintWriter(socket.getOutputStream());       //由Socket对象得到输出流,并构造PrintWriter对象              BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));      
   //由系统标准输入设备构造BufferedReader对象
           System.out.println("Client:"+is.readLine());     
   //在标准输出上打印从客户端读入的字符串                    line=sin.readLine();    
    //从标准输入读入一字符串    
    while(!line.equals("bye")){    
    //如果该字符串为 "bye",则停止循环                                    os.println(line);   
               //向客户端输出该字符串       
                         os.flush();        
                  //刷新输出流,使Client马上收到该字符串                            System.out.println("Server:"+line);                        //在系统标准输出上打印读入的字符串                  System.out.println("Client:"+is.readLine());                  //从Client读入一字符串,并打印到标准输出上                      line=sin.readLine();     
     //从系统标准输入读入一字符串     
               }  //继续循环     
   os.close();//关闭Socket输出流     
   is.close();//关闭Socket输入流     
   socket.close();//关闭Socket      
  server.close();//关闭ServerSocket   
   }catch(Exception e){      
  System.out.println("Error:"+e);   
     //出错,打印出错信息    
                          }   
               } 
 }(仅供参考)

1 Socket通讯
    网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。  在传统的UNIX环境下可以操作TCP/IP协议的接口不止Socket一个,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
2 Socket通讯的一般过程
  使用Socket进行Client/Server程序设计的一般连接过程是这样的:Server端Listen(监听)某个端口是否有连接请求,Client端向Server端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client端都可以通过Send,Write等方法与对方通信。
  对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:  (1) 创建Socket;  (2) 打开连接到Socket的输入/出流;  (3) 按照一定的协议对Socket进行读/写操作;  (4) 关闭Socket.
3 创建Socket
    java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下: 
 Socket(InetAddress address, int port); 
 Socket(InetAddress address, int port, boolean stream); 
 Socket(String host, int prot); 
 Socket(String host, int prot, boolean stream); 
 Socket(SocketImpl impl) 
 Socket(String host, int port, InetAddress localAddr, int localPort)  Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 
 ServerSocket(int port);
 ServerSocket(int port, int backlog); 
 ServerSocket(int port, int backlog, InetAddress bindAddr) 
 其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。例如:  Socket client = new Socket("127.0.01.", 80);  ServerSocket server = new ServerSocket(80);  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23,所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

    通过URL的方法openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端的CGI程序发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。CGI是公共网关接口(Common Gateway Interface)的简称,它是用户浏览器和服务器端的应用程序进行连接的接口,有关CGI程序设计,请读者参考有关书籍。  类URLConnection也在包java.net中定义,它表示Java程序和URL在网络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应的URLConnection对象。例如下面的程序段首先生成一个指向地址http://edu.chinaren.com/index.shtml的对象,然后用openConnection()打开该URL对象上的一个连接,返回一个URLConnection对象。如果连接过程失败,将产生IOException. 
Try{    
URL netchinaren = new URL ("http://edu.chinaren.com/index.shtml");  URLConnectonn tc = netchinaren.openConnection(); 
 }catch(MalformedURLException e){
      //创建URL()对象失败  …  }catch (IOException e)    {//openConnection()失败  …  }  
类URLConnection提供了很多方法来设置或获取连接参数,程序设计时最常使用的是getInputStream()和getOurputStream(),其定义为:     InputSteram getInputSteram();     OutputSteram getOutputStream();  通过返回的输入/输出流我们可以与远程对象进行通信。看下面的例子:
  URL url =new URL ("http://www.javasoft.com/cgi-bin/backwards");  //创建一URL对象  
  URLConnectin con=url.openConnection(); 
 //由URL对象获取URLConnection对象 
 DataInputStream dis=new DataInputStream (con.getInputSteam()); 
 //由URLConnection获取输入流,并构造DataInputStream对象            PrintStream ps=new PrintSteam(con.getOutupSteam()); 
 //由URLConnection获取输出流,并构造PrintStream对象 
 String  line=dis.readLine();
//从服务器读入一行 
 ps.println("client…");
//向服务器写出字符串 "client…" 
   其中backwards为服务器端的CGI程序。实际上,类URL的方法openSteam()是通过URLConnection来实现的。它等价于  openConnection().getInputStream();  基于URL的网络编程在底层其实还是基于下面要讲的Socket接口的。WWW,FTP等标准化的网络服务都是基于TCP协议的,所以本质上讲URL编程也是基于TCP的一种应用.

共10篇日记