在客户/服务器通信模式中,客户端需要主动创建与服务器的Socket(套接字),服务端收到了客户端的请求,也会创建与客户端连接的Socket。

Scoket可以看作两端通信的收发器,服务端和客户端都通过Scoket收发数据~~~

一:首先介绍Scoket的构造方法:

构造方法的重载:

复制代码
Socket()

Socket(InetAddress address, int port) throws UnknowHostException, IOException

Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException

Socket(String host, int port) throws UnknowHostException, IOException

Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
复制代码

1:解析:除了第一个不带参的构造方法,其余的构造方法都试图与服务器创建连接,如果连接成功,就返回Socket对象;如果因为某些原因连接失败,则会抛出异常。。。。。。

2:使用无参构造方法,设定等待建立连接的超时时间:

Socket socket = new Socket();
  SocketAddress remoteAddr = new InetSocketAddress("localhost",8000);
  socket.connect(remoteAddr, 60000);  //等待建立连接的超时时间为1分钟

  以上代码用于连接到本地机器上的监听8000端口的服务器程序, 等待连接的最长时间为1分钟. 如果在1分钟内连接成功则connet()方法顺利返回; 如果在1分钟内出现某种异常, 则抛出该异常; 如果超过1分钟后, 即没有连接成功, 也没有出现其他异常, 那么会抛出 SocketTimeoutException. Socket 类的 connect(SocketAddress endpoint, int timeout) 方法负责连接服务器, 参数endpoint 指定服务器的地址, 参数timeout 设定超时数据, 以毫秒为单位. 如果参数timeout 设为0, 表示永远不会超时, 默认是不会超时的. 

3: 设定服务器的地址

      除了第一个不带参数的构造方法, 其他构造方法都需要在参数中设定服务器的地址, 包括服务器的IP地址或主机名, 以及端口:

Socket(InetAddress address, int port)              //第一个参数address 表示主机的IP地址
  Socket(String host, int port)                              //第一个参数host 表示主机的名字

二. 获取Socket 的信息

   在一个Socket 对象中同时包含了远程服务器的IP 地址和端口信息, 以及客户本地的IP 地址和端口信息. 此外, 从Socket 对象中还可以获得输出流和输入流, 分别用于向服务器发送数据, 以及接收从服务器端发来的数据. 以下方法用于获取Socket的有关信息.

getInetAddress(): 获得远程服务器的IP 地址.
getPort(): 获得远程服务器的端口.
getLocalAddress(): 获得客户本地的IP 地址.
getLocalPort(): 获得客户本地的端口.
getInputStream(): 获得输入流. 如果Socket 还没有连接, 或者已经关闭, 或者已经通过 shutdownInput() 方法关闭输入流, 那么此方法会抛出IOException.
getOutputStream(): 获得输出流, 如果Socket 还没有连接, 或者已经关闭, 或者已经通过 shutdownOutput() 方法关闭输出流, 那么此方法会抛出IOException.

三. 关闭Socket

     当客户与服务器的通信结束, 应该及时关闭Socket , 以释放Socket 占用的包括端口在内的各种资源. Socket 的 close() 方法负责关闭Socket. 当一个Socket对象被关闭, 就不能再通过它的输入流和输出流进行I/O操作, 否则会导致IOException.

      为了确保关闭Socket 的操作总是被执行, 强烈建议把这个操作放在finally 代码块中:

复制代码
 Socket socket = null;
   try{
        socket = new Socket(www.javathinker.org,80);
        //执行接收和发送数据的操作
        .........
   }catch(IOException e){
         e.printStackTrace();
   }finally{
        try{
             if(socket != null)  socket.close();
       }catch(IOException e){e.printStackTrace();}
   }
复制代码

Socket 类提供了3 个状态测试方法.

isClosed(): 如果Socket已经连接到远程主机, 并且还没有关闭, 则返回true , 否则返回false .
isConnected(): 如果Socket曾经连接到远程主机, 则返回true , 否则返回false .
isBound(): 如果Socket已经与一个本地端口绑定, 则返回true , 否则返回false .

五. 设置Socket 的选项

     Socket 有以下几个选项.

复制代码
TCP_NODELAY: 表示立即发送数据.

SO_RESUSEADDR: 表示是否允许重用Socket 所绑定的本地地址.

SO_TIMEOUT: 表示接收数据时的等待超时数据.

SO_LINGER: 表示当执行Socket 的 close()方法时, 是否立即关闭底层的Socket.

SO_SNFBUF: 表示发送数据的缓冲区的大小.

SO_RCVBUF: 表示接收数据的缓冲区的大小.

SO_KEEPALIVE: 表示对于长时间处于空闲状态的Socket , 是否要自动把它关闭.

OOBINLINE: 表示是否支持发送一个字节的TCP 紧急数据.
复制代码