本文共 2911 字,大约阅读时间需要 9 分钟。
络术语中,端口并不是指物理设备,而是为了便于实现服务器与客户端直接通信所使用的抽象概念。
运行在远程计算机上的服务器软件不停地等待那些希望与目标端口连接的网络请求。当远程计算机上的操作系统接收到一个请求与目标端口连接的网络数据包时,它便唤醒正在监听网络连接请求的服务器进程,并为两者建立连接。这种连接将一直保持下去,知道被其中任何一方中止。 例:public static void main(String[] args) { try{ Socket socket = new Socket("time-A.timefreq.bldrdoc.gov", 13); socket.setSoTimeout(10000); InputStream inStream = socket.getInputStream(); try{ Scanner in = new Scanner(inStream); while(in.hasNextLine()){ String line = in.nextLine(); System.out.println(line); } }finally{ socket.close(); } }catch(IOException e){ e.printStackTrace(); } }(1).关键代码 Socket socket = new Socket("time-A.timefreq.bldrdoc.gov", 13); 用于打开一个套接字,它也是网络软件中的一个抽象概念,负责使该程序内部和外部直接的通信。我们将远程地址和端口号传递给套接字的构造器,如果连接失败它将抛出一个UnknowHostException异常;如果存在其他问题,它将抛出一个IOException异常。其中UnknowHostException是IOException异常的子类。 InputStream inStream = socket.getInputStream(); 一旦套接字被打开,java.net.Socket类中的getInputStream方法就会返回一个InputStream对象。而一旦获取了这个流,该程序将直接把每一行打印到标准输出。这个过程将一直持续到流发送完毕且服务器端口连接位置。 (2).该程序只适用于非常简单的服务器,比如“当日时间”之类的服务程序。在比较负责的网络程序中,客户端发送请求数据给服务器,而服务器可能在响应结束时并不立刻断开连接。 (3).Socket类非常简单易用,因为Java隐藏了简历网络连接和通过连接发送数据的复杂过程。实际上,java.net包提供的编程接口与操作文件时所使用的接口基本相同。 (4).Java除了支持TCP(传输控制协议)网络协议,还支持UDP(用户数据报协议),该协议可以用于发送数据包(也称为数据报),它所需付出的开销要比TCP少得多。UDP有一个重要的缺点:数据包无需按照顺序进行传递,它们甚至可能在传输过程中全部丢失。UDP要求数据包得接受者对它们进行排序,并请求发送者重新发送哪些丢失的数据包。UDP比较适合于哪些可以忍受数据包丢失的应用,例如用于音频流和视频流的传输,或者用于连续测量的应用领域。 1.套接字超时 (1)从套接字读取信息时,在可以访问数据之前,读操作将会被阻塞。如果此时主机不可达,那么应用将要等待很长得时间,并且因为受低层操作系统的限制而最终会导致超时。 对于不同的应用,应该确定合理的超时值。然后调用setSoTimeout方法设置这个超时值(单位:毫秒)。 Socket socket = new Socket("time-A.timefreq.bldrdoc.gov", 13); socket.setSoTimeout(10000); 如果已经为套接字设置了超时值,并且之后的都操作和写操作在没有完成之前就超过了时间限制,那么这些操作就会抛出SocketTimeoutException异常。 可以捕获这个异常,并对超时做出反应
try{ InputStream in = socket.getInputStream(); ... }catch(InterruptedIOException exception){ ... }(2)另外,还有一个超时问题是必须解决的。
Socket(String host, int port)该构造器会一直无限期的阻塞下去,知道建立了到达主机的初始连接为止。 可以通过先构建一个无连接的套接字,然后再使用一个超时来连接的方法解决这个问题。
Socket socket = new Socket(); socket.connect(InetSocketAddress(String hostname, int port), int timeout);
2.因特网地址 因特网地址是指用一串数字表示的主机地址,它由4个字节组成,IPv6规定为16个字节,比如192.168.1.1。通常,不用过多考虑因特网地址的问题。但是,如果需要在主机名和因特网地址之间进行转换时,可以使用InetAddress类。 只要主机操作系统支持IPv6格式的因特网地址,java.net包也将支持它。 静态的getByName方法可以返回代表某个主机的InetAddress对象 例:
InetAddress address = InetAddress.getByName("time-A.timefreq.bldrdoc.gov");
将返回一个InetAddress对象,该对象封装了一个4字节的序列:132.164.4.104。然后,可以使用getAddress方法来访问这些字节。
byte[] addressBytes = address.getAddress();
一些访问量较大的主机名通常会应用于多个因特网地址,以实现负载均衡。可以通过getAllByName方法来获取所有主机。
InetAddress[] addresses = InetAddress.getAllByName(host);
有时可能需要知道本地主机的地址。如果只是要求得到localhost的地址,那总会得到地址127.0.0.1。此时,可以使用静态的getLocaHost方法来得到本地主机的地址。
InetAddress address = InetAddress.getLocaHost();
转载地址:http://payci.baihongyu.com/