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