📜  Java-网络

📅  最后修改于: 2020-12-21 01:52:25             🧑  作者: Mango


术语网络编程是指编写跨多个设备(计算机)执行的程序,其中所有设备都使用网络相互连接。

J2SE API的java.net包包含提供低级通信详细信息的类和接口的集合,使您可以编写专注于解决当前问题的程序。

java.net包提供对两种常见网络协议的支持-

  • TCP -TCP代表传输控制协议,它允许两个应用程序之间进行可靠的通信。 TCP通常在Internet协议(称为TCP / IP)上使用。

  • UDP -UDP代表用户数据报协议,这是一种无连接协议,允许在应用程序之间传输数据包。

本章对以下两个主题有很好的理解-

  • 套接字编程-这是网络中使用最广泛的概念,已经对其进行了非常详细的说明。

  • URL处理-这将单独介绍。单击此处以了解Java语言中的URL处理

套接字编程

套接字提供使用TCP的两台计算机之间的通信机制。客户端程序在其通信结束时创建一个套接字,然后尝试将该套接字连接到服务器。

建立连接后,服务器将在其通信结束时创建一个套接字对象。客户端和服务器现在可以通过写入和读取套接字进行通信。

java.net.Socket类代表一个套接字,而java.net.ServerSocket类则为服务器程序提供一种机制,以侦听客户端并与客户端建立连接。

使用套接字在两台计算机之间建立TCP连接时,将执行以下步骤-

  • 服务器实例化一个ServerSocket对象,表示要在哪个端口号上进行通信。

  • 服务器调用ServerSocket类的accept()方法。该方法一直等到客户端在给定端口上连接到服务器。

  • 服务器等待之后,客户端实例化一个Socket对象,指定服务器名称和要连接的端口号。

  • Socket类的构造函数尝试将客户端连接到指定的服务器和端口号。如果建立了通信,则客户端现在具有一个能够与服务器通信的Socket对象。

  • 在服务器端,accept()方法返回对服务器上与客户端套接字连接的新套接字的引用。

建立连接后,可以使用I / O流进行通信。每个套接字都有一个OutputStream和一个InputStream。客户端的OutputStream连接到服务器的InputStream,并且客户端的InputStream连接到服务器的OutputStream。

TCP是一种双向通信协议,因此可以同时在两个流之间发送数据。以下是有用的类,提供了用于实现套接字的完整方法集。

ServerSocket类方法

服务器应用程序使用java.net.ServerSocket类获取端口并侦听客户端请求。

ServerSocket类具有四个构造函数-

Sr.No. Method & Description
1

public ServerSocket(int port) throws IOException

Attempts to create a server socket bound to the specified port. An exception occurs if the port is already bound by another application.

2

public ServerSocket(int port, int backlog) throws IOException

Similar to the previous constructor, the backlog parameter specifies how many incoming clients to store in a wait queue.

3

public ServerSocket(int port, int backlog, InetAddress address) throws IOException

Similar to the previous constructor, the InetAddress parameter specifies the local IP address to bind to. The InetAddress is used for servers that may have multiple IP addresses, allowing the server to specify which of its IP addresses to accept client requests on.

4

public ServerSocket() throws IOException

Creates an unbound server socket. When using this constructor, use the bind() method when you are ready to bind the server socket.

如果ServerSocket构造函数未引发异常,则意味着您的应用程序已成功绑定到指定的端口,并准备接受客户端请求。

以下是ServerSocket类的一些常用方法-

Sr.No. Method & Description
1

public int getLocalPort()

Returns the port that the server socket is listening on. This method is useful if you passed in 0 as the port number in a constructor and let the server find a port for you.

2

public Socket accept() throws IOException

Waits for an incoming client. This method blocks until either a client connects to the server on the specified port or the socket times out, assuming that the time-out value has been set using the setSoTimeout() method. Otherwise, this method blocks indefinitely.

3

public void setSoTimeout(int timeout)

Sets the time-out value for how long the server socket waits for a client during the accept().

4

public void bind(SocketAddress host, int backlog)

Binds the socket to the specified server and port in the SocketAddress object. Use this method if you have instantiated the ServerSocket using the no-argument constructor.

当ServerSocket调用accept()时,该方法直到客户端连接后才返回。客户端连接后,ServerSocket在未指定的端口上创建一个新的Socket,并返回对该新Socket的引用。现在,客户端和服务器之间存在TCP连接,并且可以开始通信。

套接字类方法

java.net.Socket类表示客户端和服务器都用于相互通信的套接字。客户端通过实例化一个实例来获得一个Socket对象,而服务器从accept()方法的返回值中获得一个Socket对象。

Socket类具有五个构造函数,客户端可使用这些构造函数连接到服务器-

Sr.No. Method & Description
1

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

This method attempts to connect to the specified server at the specified port. If this constructor does not throw an exception, the connection is successful and the client is connected to the server.

2

public Socket(InetAddress host, int port) throws IOException

This method is identical to the previous constructor, except that the host is denoted by an InetAddress object.

3

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.

Connects to the specified host and port, creating a socket on the local host at the specified address and port.

4

public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.

This method is identical to the previous constructor, except that the host is denoted by an InetAddress object instead of a String.

5

public Socket()

Creates an unconnected socket. Use the connect() method to connect this socket to a server.

当Socket构造函数返回时,它不只是实例化Socket对象,而是实际上尝试连接到指定的服务器和端口。

此处列出了Socket类中感兴趣的一些方法。注意,客户端和服务器都有一个Socket对象,因此客户端和服务器都可以调用这些方法。

Sr.No. Method & Description
1

public void connect(SocketAddress host, int timeout) throws IOException

This method connects the socket to the specified host. This method is needed only when you instantiate the Socket using the no-argument constructor.

2

public InetAddress getInetAddress()

This method returns the address of the other computer that this socket is connected to.

3

public int getPort()

Returns the port the socket is bound to on the remote machine.

4

public int getLocalPort()

Returns the port the socket is bound to on the local machine.

5

public SocketAddress getRemoteSocketAddress()

Returns the address of the remote socket.

6

public InputStream getInputStream() throws IOException

Returns the input stream of the socket. The input stream is connected to the output stream of the remote socket.

7

public OutputStream getOutputStream() throws IOException

Returns the output stream of the socket. The output stream is connected to the input stream of the remote socket.

8

public void close() throws IOException

Closes the socket, which makes this Socket object no longer capable of connecting again to any server.

InetAddress类方法

此类表示Internet协议(IP)地址。以下是进行套接字编程时需要的有用方法-

Sr.No. Method & Description
1

static InetAddress getByAddress(byte[] addr)

Returns an InetAddress object given the raw IP address.

2

static InetAddress getByAddress(String host, byte[] addr)

Creates an InetAddress based on the provided host name and IP address.

3

static InetAddress getByName(String host)

Determines the IP address of a host, given the host’s name.

4

String getHostAddress()

Returns the IP address string in textual presentation.

5

String getHostName()

Gets the host name for this IP address.

6

static InetAddress InetAddress getLocalHost()

Returns the local host.

7

String toString()

Converts this IP address to a String.

套接字客户端示例

下面的GreetingClient是一个客户端程序,该程序通过使用套接字连接到服务器并发送问候语,然后等待响应。

// File Name GreetingClient.java
import java.net.*;
import java.io.*;

public class GreetingClient {

   public static void main(String [] args) {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try {
         System.out.println("Connecting to " + serverName + " on port " + port);
         Socket client = new Socket(serverName, port);
         
         System.out.println("Just connected to " + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
         
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         
         System.out.println("Server says " + in.readUTF());
         client.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

套接字服务器示例

以下GreetingServer程序是服务器应用程序的示例,该应用程序使用Socket类在命令行参数指定的端口号上侦听客户端-

// File Name GreetingServer.java
import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException {
      serverSocket = new ServerSocket(port);
      serverSocket.setSoTimeout(10000);
   }

   public void run() {
      while(true) {
         try {
            System.out.println("Waiting for client on port " + 
               serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            
            System.out.println("Just connected to " + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
               + "\nGoodbye!");
            server.close();
            
         } catch (SocketTimeoutException s) {
            System.out.println("Socket timed out!");
            break;
         } catch (IOException e) {
            e.printStackTrace();
            break;
         }
      }
   }
   
   public static void main(String [] args) {
      int port = Integer.parseInt(args[0]);
      try {
         Thread t = new GreetingServer(port);
         t.start();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

编译客户端和服务器,然后按以下方式启动服务器-

$ java GreetingServer 6066
Waiting for client on port 6066...

检查客户端程序,如下所示:

输出

$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!