Java网络编程 多种多样的连接数据库的方式

开发 后端
我们可以通过6个重载构造函数以不同的方式来连接服务器。这6个重载的构造函数可以分为两类:自动选择IP和手动绑定IP。

一、通过构造方法连接服务器

我们可以通过6个重载构造函数以不同的方式来连接服务器。这6个重载的构造函数可以分为两类:

1. 自动选择IP

这种方式是最常用的。所谓自动选择IP,是指当本机有多块网卡或者在一个网卡上绑定了多个IP时,Socket类会自动为我们选择一个可用的IP。在上述6个构造方法中有4个是使用这种方法来连接服务器的。   
      

  1. <!--[if !supportLists]-->(1)  
  2.    <!--[endif]-->public Socket(String host, int port)   

这是最常用的构造方法,在前面的例子中就是使用的这个构造方法。在使用时只需要提供一个字符串类型的IP或域名以及一个整型的端口号即可。在这个构造方法中可能会抛出两个错误:UnknownHostException和IOException。发生***个错误的原因是我们提供的host并不存在或不合法,而其它的错误被归为IO错误。因此,这个构造方法的完整定义是:

public Socket(String host, int port) throws UnknownHostException, IOException

(2) public Socket(InetAddress inetaddress, int port)

这个构造方法和***种构造方法类似,只是将字符串形式的host改为InetAddress对象类型了。在这个构造方法中之所以要使用InetAddress类主要是因为考虑到在程序中可能需要使用Socket类多次连接同一个IP或域名,这样使用InetAddress类的效率比较高。另外,在使用字符串类型的host连接服务器时,可能会发生两个错误,但使用InetAddress对象来描述host,只会发生IOException错误,这是因为当你将IP或域名传给InetAddress时,InetAddress会自动检查这个IP或域名,如果这个IP或域名无效,那么InetAddress就会抛出UnknownHostException错误,而不会由Socket类的构造方法抛出。因此,这个构造方法的完整定义是:

public Socket(InetAddress inetaddress, int port) throws IOException

(3) public Socket(String host, int port, boolean stream)

这个构造方法和***种构造方法差不多,只是多了一个boolean类型的stream参数。如果这个stream为true,那么这个构造方法和***种构造方法完全一样。如果stream为false,则使用UDP协议建立一个UDP连接(UDP将在下面的章节详细讨论,在这里只要知道它和TCP***的区别是UDP是面向无连接的,而TCP是面向有连接的),也许是当初Sun的开发人员在编写Socket类时还未考虑编写处理UDP连接的DatagramSocket类,所以才将建立UDP连接的功能加入到Socket类中,不过Sun在后来的JDK中加入了DatagramSocket类,所以,这个构造方法就没什么用了,因此,Sun将其设为了Deprecated标记,也就是说,这个构造方法在以后的JDK版本中可以会被删除。其于以上原因,在使用Java编写网络程序时,尽量不要使用这个构造方法来建立UDP连接。

(4) public Socket(InetAddress inetaddress, int port, boolean flag)

这个构造方法和第三种构造方法的flag标记的含义一样,也是不建议使用的。

下面的代码演示上述4种构造方法的使用:        

  1.       package mysocket;  
  2.  
  3. import java.net.*;  
  4. import java.io.*;  
  5.  
  6. public class MoreConnection  
  7. {  
  8.     private static void closeSocket(Socket socket)  
  9.     {  
  10.         if (socket != null)  
  11.             try  
  12.             {  
  13.                 socket.close();  
  14.             }  
  15.             catch (Exception e) { }  
  16.     }  
  17.  
  18.     public static void main(String[] args)  
  19.     {  
  20.         Socket socket1 = nullsocket2 = nullsocket3 = nullsocket4 = null;  
  21.         try  
  22.         {  
  23.             // 如果将www.ptpress.com.cn改成其它不存在的域名,  
  24.                将抛出UnknownHostException错误  
  25.             // 测试public Socket(String host, int port)  
  26.             socket1 = new Socket("www.ptpress.com.cn", 80);  
  27.             System.out.println("socket1连接成功!");  
  28.             // 测试public Socket(InetAddress inetaddress, int port)  
  29.             socket2 = new Socket(InetAddress.getByName("www.ptpress.com.cn"), 80);  
  30.             System.out.println("socket2连接成功!");  
  31.  
  32.             // 下面的两种建立连接的方式并不建议使用  
  33.             // 测试public Socket(String host, int port, boolean stream)  
  34.             socket3 = new Socket("www.ptpress.com.cn", 80, false);  
  35.             System.out.println("socket3连接成功!");  
  36.             // 测试public Socket(InetAddress inetaddress, int i, boolean flag)  
  37.             socket4 = new Socket(InetAddress.getByName("www.ptpress.com.cn"), 80, false);  
  38.             System.out.println("socket4连接成功!");  
  39.         }  
  40.         catch (UnknownHostException e)  
  41.         {  
  42.             System.out.println("UnknownHostException 被抛出!");  
  43.         }  
  44.         catch (IOException e)  
  45.         {  
  46.             System.out.println("IOException 被抛出!");  
  47.         }  
  48.         finally  
  49.         {  
  50.             closeSocket(socket1);  
  51.             closeSocket(socket2);  
  52.             closeSocket(socket3);  
  53.             closeSocket(socket4);  
  54.         }  
  55.     }  
  56. }   

#p#

在上面代码中的***通过finally关闭了被打开的Socket连接,这是一个好习惯。因为只有在将关闭Socket连接的代码写在finally里,无论是否出错,都会执行这些代码。但要注意,在关闭Socket连接之前,必须检查Socket对象是否为null,这是因为错误很可能在建立连接时发生,这样Socket对象就没有建立成功,也就用不着关闭了。
  

2.手动绑定IP

当本机有多个IP时(这些IP可能是多块网卡上的,也可能是一块网卡上绑定的多个IP),在连接服务器时需要由客户端确定需要使用哪个IP。这样就必须使用Socket类的另外两个构方法来处理。下面让我们来看看这两个构造方法是如何来使用特定的IP来连接服务器的。

public Socket(String host, int port, InetAddress inetaddress, int localPort)

这个构造方法的参数分为两部分,***部分为前两个参数:host和port,它们分别表示要连接的服务器的IP和端口号。第二部分为后两个参数:inetaddress和localPort。其中inetaddress则表示要使用的本地的IP,而localPort则表示要绑定的本地端口号。这个localPort这以设置为本机的任何未被绑定的端口号。如果将localPort的值设为0,java将在1024到65,535之间随即选择一个未绑定的端口号。因此,在一般情况下将localPort设为0。

public Socket(InetAddress inetaddress, int port, InetAddress inetaddress1, int localPort)

这个构造方法和***个构造方法基本相同,只是将***个参数host换成了inetaddress。其它的使用方法和***个构造方法类似。

在下面的代码中将使用这两个构造方法来做一个实验。我们假设有两台计算机:PC1和PC2。PC1和PC2各有一块网卡。PC1绑定有两个IP:192.168.18.252和200.200.200.200。PC2绑定有一个IP:200.200.200.4。PC1和PC2的子网掩码都是255.255.255.0。而PC1的默认网关为:192.168.28.254。下面的代码需要在PC1上运行。                  

  1. package mysocket;  
  2.  
  3. import java.net.*;  
  4.  
  5. public class MoreConnection1  
  6. {  
  7.     public static void main(String[] args)  
  8.     {  
  9.         try  
  10.         {  
  11.             InetAddress localAddress1 = InetAddress.getByName("200.200.200.200");  
  12.             InetAddress localAddress2 = InetAddress.getByName("192.168.18.252");  
  13.             // 如果将localAddress1改成localAddress2,socket1无法连接成功  
  14.             Socket socket1 = new Socket("200.200.200.4", 80, localAddress1, 0);  
  15.             System.out.println("socket1连接成功!");  
  16.             Socket socket2 = new Socket("www.ptpress.com.cn", 80, localAddress2, 0);  
  17.             System.out.println("socket2连接成功!");  
  18.             // 下面的语句将抛出一个IOException错误  
  19.             Socket socket3 = new Socket("www.ptpress.com.cn", 80, localAddress1, 0);  
  20.             System.out.println("socket3连接成功!");  
  21.             socket1.close();  
  22.             socket2.close();  
  23.             socket3.close();  
  24.         }  
  25.         catch (Exception e)  
  26.         {  
  27.             System.out.println(e.getMessage());  
  28.         }  
  29.     }  
  30. }   
  31.  

运行上面代码的输出结果如下:

socket1连接成功!

socket2连接成功!

Connection timed out: connect

从上面的输出结果可以看出,socket1和socket2已经连接成功,而socket3并未连接成功。从例程4-8可以看出,socket1在连接时使用localAddress1绑定到了200.200.200.200上,而PC2的IP是200.200.200.4,因此,socket1所使用的IP和PC2的IP在同一个网段,所以socket1可以连接成功。如果将localAddress1改成localAddress2后,socket1将无法连接成功。另外两个Socket连接socket2和socket3是通过Internet连接www.ptpress.com.cn。它们所不同的是socket2绑定的是192.168.18.252,而socket3绑定的是200.200.200.200。它们执行的结果是socket2可以连接成功,而socket3连接失败。这是因为socket2所绑定的IP和PC1的默认网关192.168.18.254在同一个网段,因此,socket2可以连接到Internet。而socket3所绑定的IP和PC1的IP不在同一个网段,因此,socket3将无法连接到Internet。

二、通过connect方法连接服务器

Socket类不仅可以通过构造方法直接连接服务器,而且还可以建立未连接的Socket对象,并通过connect方法来连接服务器。Socket类的connect方法有两个重载形式:

1. public void connect(SocketAddress endpoint) throws IOException

Socket类的connect方法和它的构造方法在描述服务器信息(IP和端口)上有一些差异。在connect方法中并未象构造方法中以字符串形式的host和整数形式的port作为参数,而是直接将IP和端口封装在了SocketAddress类的子类InetSocketAddress中。可按如下形式使用这个connect方法:               

Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, port));

2. public void connect(SocketAddress endpoint, int timeout) throws IOException

这个connect方法和***个connect类似,只是多了一个timeout参数。这个参数表示连接的超时时间,单位是毫秒。使用timeout设为0,则使用默认的超时时间。

在使用Socket类的构造方法连接服务器时可以直接通过构造方法绑定本地IP,而connect方法可以通过Socket类的bind方法来绑定本地IP。例程4-9演示如何使用connect方法和bind方法。             
            

  1.  package mysocket;  
  2.  
  3. import java.net.*;  
  4.  
  5. public class MoreConnection2  
  6. {  
  7.     public static void main(String[] args)  
  8.     {  
  9.         try  
  10.         {  
  11.             Socket socket1 = new Socket();  
  12.             Socket socket2 = new Socket();  
  13.             Socket socket3 = new Socket();  
  14.             socket1.connect(new InetSocketAddress("200.200.200.4", 80));  
  15.             socket1.close();  
  16.             System.out.println("socket1连接成功!");               
  17.             /*  
  18.                将socket2绑定到192.168.18.252将产生一个IOException错误    
  19.             socket2.bind(new InetSocketAddress("192.168.18.252", 0));  
  20.             */  
  21.             socket2.bind(new InetSocketAddress("200.200.200.200", 0));  
  22.             socket2.connect(new InetSocketAddress("200.200.200.4", 80));  
  23.                
  24.             socket2.close();  
  25.             System.out.println("socket2连接成功!");  
  26.  
  27.             socket3.bind(new InetSocketAddress("192.168.18.252", 0));  
  28.             socket3.connect(new InetSocketAddress("200.200.200.4", 80),  
  29.                              2000);              
  30.             socket3.close();  
  31.             System.out.println("socket3连接成功!");  
  32.         }  
  33.         catch (Exception e)  
  34.         {  
  35.             System.out.println(e.getMessage());  
  36.         }  
  37.     }  
  38. }   
  39.  

上面的代码的输出结果为:               

socket1连接成功!

socket2连接成功!
Connection timed out: connect

在上面代码中的socket3连接服务器时为其设置了超时时间(2000毫秒),因此,socket3在非常短的时间就抛出了IOException错误。 

【编辑推荐】

  1. 专题:Java实用开发全集
  2. Java开发者盛宴:JavaOne 2009技术前瞻
  3. 实战Java多线程编程之不提倡的方法
  4. Flex连接Java EE的技术选择
  5. 高手Java核心技术学习笔记
责任编辑:张燕妮 来源: blogjava
相关推荐

2015-02-12 14:49:36

CGToast状态栏提示Status

2019-03-27 14:41:41

Python数据库Windows

2009-07-17 15:34:37

Java Swing连接数据库

2021-07-22 23:40:15

数字人民币支付宝微信

2010-10-12 12:00:42

MySQL连接

2013-04-23 10:09:35

云计算亚马逊混合云

2009-07-16 11:04:17

Jython连接数据库

2011-03-16 17:14:17

JavaBean数据库

2009-07-06 17:23:34

JDBC连接数据库

2018-01-04 10:43:43

OracleMysqlJava

2010-05-25 18:21:28

MySQL连接数据库

2011-04-18 09:29:40

数据库连接数

2009-08-18 11:23:11

2011-08-16 18:40:59

SQL Server 数据库引擎

2009-03-19 10:08:09

C#数据库查询

2011-07-05 09:54:04

2010-08-04 10:32:56

Flex连接数据库

2009-07-20 15:56:08

JDBC连接数据库步骤

2009-07-14 17:18:23

JDBC怎么连接数据库

2009-08-25 14:05:06

C#连接数据库代码
点赞
收藏

51CTO技术栈公众号