Java网络(Socket编程)

网络编程指的是编写跨多个设备(计算机)执行的程序,设备使用网络彼此连接。

J2SE API的java.net包中包含一组类和接口,它们提供低级别的通信详细信息,开发者可编写专注于解决手头问题的程序。

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

  • TCP - TCP代表传输控制协议,它允许两个应用程序之间的可靠通信。TCP通常用于Internet协议,称为TCP/IP
  • UDP - UDP代表用户数据报协议,这是一种无连接协议,允许在应用程序之间传输数据包。

本章为这两个协议准备了两个示例,以便可以更好的理解 -

  • 套接字编程 - 它是网络中使用最广泛的概念,在本节中将进行非常详细的解释。
  • URL处理 - 它将在单独一节中详细介绍。单击此处以了解Java语言中的URL处理

1. 套接字编程

套接字是使用TCP提供通信机制在两台计算机之间进行通信。客户端程序在通信的末尾创建一个套接字,并尝试将套接字连接到服务器。

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

java.net.Socket类表示一个套接字,java.net.ServerSocket类为服务器程序提供了一种监听客户端并与它们建立连接的机制。

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

  • 服务器实例化ServerSocket对象,表示要在哪个端口号上进行通信。
  • 服务器调用ServerSocket类的accept()方法。此方法等待,直到客户端连接到给定端口上的服务器。
  • 在服务器等待之后,客户端实例化Socket对象,指定要连接的服务器名称(IP地址)和端口号。
  • Socket类的构造函数尝试将客户端连接到指定的服务器和端口号。如果建立了通信,则客户端现在具有能够与服务器通信的Socket对象。
  • 在服务器端,accept()方法返回对连接到客户端套接字的服务器上的新套接字的引用。

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

TCP是双向通信协议,因此可以同时跨两个流发送数据。以下是套接字实现类的方法 -

2. ServerSocket类方法

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

ServerSocket类有四个构造函数 -

编号构造函数描述
1public ServerSocket(int port) throws IOException尝试创建绑定到指定端口的服务器套接字。如果端口已被另一个应用程序绑定,则会发生异常。
2public ServerSocket(int port, int backlog) throws IOException与前上面构造函数类似,backlog参数指定要在等待队列中存储的传入客户端的数量。
3public ServerSocket(int port, int backlog, InetAddress address) throws IOException与前一个构造函数类似,InetAddress参数指定要绑定的本地IP地址。InetAddress用于可能具有多个IP地址的服务器,允许服务器指定哪个IP地址接受客户端请求。
4public ServerSocket() throws IOException创建未绑定的服务器套接字。使用此构造函数时,在准备绑定服务器套接字时使用bind()方法。

如果ServerSocket构造函数没有抛出异常,则表示应用程序已成功绑定到指定的端口并准备好进行客户端请求。

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

编号方法描述
1public int getLocalPort()返回服务器套接字正在侦听的端口。如果在构造函数中传入0作为端口号并让服务器自己打开端口,则此方法很有用。
2public Socket accept() throws IOException等待传入的客户端。假设已使用setSoTimeout()方法设置超时值,此方法将阻塞,直到客户端连接到指定端口上的服务器或套接字超时。否则,此方法无限期地阻塞。
3public void setSoTimeout(int timeout)设置服务器套接字在accept()期间等待客户端的时间的超时值。
4public void bind(SocketAddress host, int backlog)将套接字绑定到SocketAddress对象中的指定服务器和端口。如果已使用无参数构造函数实例化ServerSocket,请使用此方法。

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

3. Socket类方法

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

Socket类有五个构造函数,客户端用它们连接到服务器 -

编号方法描述
1public Socket(String host, int port) throws UnknownHostException, IOException此方法尝试连接到指定端口上的指定服务器。如果此构造函数未引发异常,则连接成功并且客户端连接到服务器。
2public Socket(InetAddress host, int port) throws IOException此方法与前一个构造函数相同,只是主机由InetAddress对象表示。
3public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException连接到指定的主机和端口,在指定地址和端口的本地主机上创建套接字。
4public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException此方法与前一个构造函数相同,只是主机由InetAddress对象表示。
5public Socket()创建一个未连接的套接字。使用connect()方法将此套接字连接到服务器。

Socket构造函数返回时,它不是简单地实例化Socket对象,而是实际上尝试连接到指定的服务器和端口。
下面列出了Socket类中一些重要的方法。注意,客户端和服务器都有一个Socket对象,因此客户端和服务器都可以调用这些方法。

编号方法描述
1public void connect(SocketAddress host, int timeout) throws IOException将套接字连接到指定的主机。仅当使用无参数构造函数实例化Socket时才需要此方法。
2public InetAddress getInetAddress()返回此套接字连接到的另一台计算机的地址。
3public int getPort()返回套接字在远程计算机上绑定的端口。
4public int getLocalPort()返回套接字在本地计算机上绑定的端口。
5public SocketAddress getRemoteSocketAddress()返回远程套接字的地址。
6public InputStream getInputStream() throws IOException返回套接字的输入流,输入流连接到远程套接字的输出流。
7public OutputStream getOutputStream() throws IOException返回套接字的输出流。输出流连接到远程套接字的输入流。
8public void close() throws IOException关闭套接字,此Socket对象不再能够再次连接到任何服务器。

4. InetAddress类方法

InetAddress类表示Internet协议(IP)地址。以下是执行套接字编程时需要的一些重要方法 -

编号方法描述
1static InetAddress getByAddress(byte[] addr)给定原始IP地址返回InetAddress对象。
2static InetAddress getByAddress(String host, byte[] addr)根据提供的主机名和IP地址创建InetAddress。
3static InetAddress getByName(String host)根据主机名称确定主机的IP地址。
4String getHostAddress()返回文本表示中的IP地址字符串。
5String getHostName()获取此IP地址的主机名。
6static InetAddress InetAddress getLocalHost()返回本地主机。
7String toString()将此IP地址转换为String

套接字客户端示例

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

// 文件名称: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();
      }
   }
}

Java

套接字服务器示例

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

// 文件: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

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

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

Shell

接下来运行客户端程序 -

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

原文链接:https://www.yiibai.com/java/java_networking.html
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值