Socket学习2

来源:互联网 发布:mac截图后文件在哪里 编辑:程序博客网 时间:2024/05/28 11:51

2.1接收和关闭与客户端的连接

ServeSocket的accept()方法从连接请求队列中取出一个与客户端的连接,然后创建于客户端连接Socket对象,并将它返回。如果队列中没有连接请求,accept()方法就一直等待

,直到接收到连接请求才返回。

        接下来,服务器从Socket对象中获得输入流和输出流,就能与客户交互数据。当服务器正在进行发送数据的操作时,如果客户端断开了连接,那么服务器就会抛出IOException的之类异常SocketException异常:java.net.SocketException:Connection reset by peer

这只是服务器与单个客户通信中出现的异常,这种异常应该被捕获,使得服务器能继续与其他客户通信。

一下代码采用了单线程服务器采用的通信流程:

        public void  serve()

    {

       while(true)

       {

           Socket socket=null;

              try{

                   socket=serveSocket.accept();

                   System.out.println("new connection accept:"+socket.getInetAddress()

+":"+socket.getPort());

                //接收和发送数据

                  }catch(Exception  e){

                     e.printStackTrace();

                 }finally{

                  try{

                       if(socket!=null)

                        socket.close();

                       }catch(Exception e){

                           e.printStackTrace();

                         }

 

                 }

       }

    }

与单个客户通信的代码放在一个try代码块中,如果遇到异常,该异常被catch代码块捕获

try代码块后面还有一个finally代码块,它保证不管与客户端通信正常结束还是异常结束,最后都会关闭Socket,断开与这个客户的连接

2.2关闭ServeSocket

 ServeSocket 的close()方法使服务器释放被占用的端口,并且断开与所有客户的连接。当一个服务器程序运行结束时,即使没有执行ServeSocket的close()方法,操作系统也会释放这个服务器占用的端口,因此,服务器程序并不一定要在结束之前执行ServeSocket的close()方法。

在某些情况下,如果希望直接释放服务器端口,以便让其他程序占用该端口,则可以显示调用ServeSocket的close()方法。例如一下代码用于扫描1--65535之间的端口号,如果ServeSocket成功创建,意味着该端口未被其他服务器进程绑定,否则说明该端口已经被其他进程占用:

for(int port=1;port<=65535;port++)

{

try{

ServeSockt   serveSocket=new ServeSocket(port);

serveSocket.close();

}catch(IOException e){

System.out.println("端口"+port+"已经被其他服务器进程占用");

}

}

  以上程序代码创建了一个ServeSockt 对象后,就马上关闭它,以便及时释放它占用的端口,从而避免程序临时占用系统的大多数端口。

ServeSockt 的isClose()端口方法判断ServeSockt 是否与一个端口绑定,只要ServeSockt 与一个端口绑定,即使它已经关闭,isBind()方法也会返回true。如果需要确定一个ServeSockt 已经与特定端口绑定,并且还没有被关闭,则可以采用以下方式:

boolean    isOpen=serveSocket.isBind()&&serveSocket.isClose();

2.3获取ServeSocket的信息

ServeSocket的以下两个get方法可分别获得服务器绑定的IP地址,以及绑定的端口:

~public InetAddress  getInetAddress ();

~public int getLocalPort();

前面已经讲到,在构造ServeSocket时,如果把端口设置为0,那么由操作系统为服务器分配一个端口(称为匿名端口),程序只要调用getLocalPort()方法就能获知这个端口号,一下程序可以验证

package com.sxt.socket.sersocket;

import java.io.IOException;
import java.net.ServerSocket;

/**
 * @author jt
 *2015-12-4 下午9:28:04
 *
 */
public class RandomPort {

 /**
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
  ServerSocket serveSocket=new ServerSocket();
  System.out.println("监听的端口号为:"+serveSocket.getLocalPort());
 }

}

 

多数程序会监听固定端口,这样便于客户程序访问服务器,匿名端口一般适用于服务器与客户进程之间的临时通信,通信结束,就断开连接,并且ServeSocket占用的临时端口也会释放。

FTP之间(文件传输协议)就使用了匿名端口

 

FTP使用两个并行的TCP连接:一个是控制连接,一个数数据连接。控制连接用于在客户和服务器之间发送控制信息,如用户名和口令,改变远程目录的命令或则上传和下载的命令。数据连接用于传送文件。TCP服务器在21端口上监听控制连接,如果客户要求上传和下载文件,就另外建立一个数据连接,通过它来传送数据。数据连接的建立有两种连接方式:

(1)如下图,TCP服务器在20端口上监听数据连接,TCP客户主动请求建立与该端口的连接。

(2)如下图,首先TCP客户创建一个监听匿名端口的ServerSocket,在把这个ServerSocket监听的端口号(调用ServerSocket的getLocalport()方法就能得到端口号)发送给TCP服务器。然后由TCP服务器主动请求建立与客户端的连接

以上第二种方式就是使用了匿名端口,并且是在客户端使用的,用于和服务器建立临时的连接。在实际应用中,在服务器端也可以使用匿名端口。

 

 

 

 

 

0 0
原创粉丝点击