Java Socket编程

434 阅读3分钟

Java Socket编程

本文描述了非常基本的单向客户端与服务器模型,其中客户端进行连接,将消息发送到服务器,服务器使用套接字连接显示消息。这一过程非常繁琐,但是Java的net网络包提供了API,负责所有连接工作,从而使Java的网络编程变得更加简单。

客户端

建立套接字连接

想要与另外计算机建立通信,我们需要socket连接。socket连接意味着两台计算机都有对方的网络IP和TCP端口的信息。java.net.Socket类中关于socket的操作如下:

Socket socket = new Socket("localhost", 8080)
  • 第一个参数:服务器的IP地址。
  • 第二个参数:监听的TCP端口。

通信

为了通过套接字实现通信,输入输出的数据都采用了流数据。

关闭连接

一旦消息发送到服务器,套接字连接将显式关闭。

而对于客户端,它将一直读取用户输入的数据并发送至服务器,直到某个终止条件。

// A Java program for a Client

import java.net.*;
import java.io.*;

public class Client {
    // initialize socket and input output streams
    private Socket socket = null;
    private DataInputStream input = null;
    private DataOutputStream out = null;

    // constructor to put ip address and port
    public Client(String address, int port) {
        // establish a connection
        try {
            socket = new Socket(address, port);
            System.out.println("Connected");

            // takes input from terminal
            input = new DataInputStream(System.in);

            // sends output to the socket
            out = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        // string to read message from input
        String line = "";

        // keep reading until "Over" is input
        while (!line.equals("Over")) {
            try {
                line = input.readLine();
                out.writeUTF(line);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // close the connection
        try {
            input.close();
            out.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Client client = new Client("127.0.0.1", 5000);
    }
}

服务器

建立连接

运行服务器程序需要两种类型的套件字。

  • ServerSocket:监听客户端请求,一个客户端会对应一个Socket
  • 普通旧套接字:用来与客户端通信

通信

getOutputStream()方法用于通过套接字来发送输出。

关闭连接

完成后,重要的是通过关闭套接字以及输入/输出流来关闭连接。

// A Java program for a Server

import java.net.*;
import java.io.*;

public class Server {
    //initialize socket and input stream
    private Socket socket = null;
    private ServerSocket server = null;
    private DataInputStream in = null;

    // constructor with port
    public Server(int port) {
        // starts server and waits for a connection
        try {
            server = new ServerSocket(port);
            System.out.println("Server started");

            System.out.println("Waiting for a client ...");

            socket = server.accept();
            System.out.println("Client accepted");

            // takes input from the client socket
            in = new DataInputStream(
                    new BufferedInputStream(socket.getInputStream()));

            String line = "";

            // reads message from client until "Over" is sent
            while (!line.equals("Over")) {
                try {
                    line = in.readUTF();
                    System.out.println(line);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Closing connection");

            // close connection
            socket.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Server server = new Server(5000);
    }
}

重点

  • 服务器应用程序在特定的端口5000上创建一个ServerSocket,监听端口5000传入的客户端请求
  • 然后,服务器创建一个新的套接字以与客户端进行通信
socket = server.accept()
  • accept()方法会阻塞等待,直到客户端连接到服务器
  • 然后,使用getInputStream方法从套接字获取输入,服务器一直会接收消息,直到客户端发送“结束标志”为止
  • 完成后,我们通过关闭套接字和输入流来关闭连接

运行

打开两个终端,一个运行服务器程序,一个运行客户端程序。

首先运行服务器程序,然后运行客户端程序。

服务器程序首先输出:

Server started
Waiting for a client ...

启动客户端程序后,如果成功连接,客户端程序输出:

Connected

此时服务器程序会输出:

Client accepted