Socket支持下的点对点通信的实现(服务端与客户端注释)
分别写出服务器端和客户端应用程序的代码,程序必须有相应的说明及注释。
服务器端程序代码注释(仅供参考)
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class Server extends JFrame implements ActionListener {
ServerSocket ss = null; // ServerSocket对象
Socket s = null; // Socket对象
private DataInputStream is = null; // 输入流
private DataOutputStream os = null; // 输出流
private boolean connected = false; // 是否连接标志
JLabel ipLabel = new JLabel(); // 显示本机IP地址的标签
JLabel portLabel = new JLabel("端口"); // 显示端口号的标签
JTextField portTextField = new JTextField("8000"); // 端口号输入框
JButton listenButton = new JButton("监听"); // 监听按钮
JButton closeButton = new JButton("关闭"); // 关闭按钮
JPanel panel = new JPanel(); // 包含各种控件的面板
JTextField inputTextField = new JTextField(); // 输入框
JTextArea contentTextArea = new JTextArea(); // 显示接收到的数据的文本区域
Thread recvThread = new Thread(new RecvThread()); // 接收数据的线程
// 构造函数
public Server() {
setTitle("服务器端"); // 窗口标题
setLayout(new BorderLayout()); // 设置布局为边界布局
panel.setLayout(new FlowLayout()); // 面板使用流式布局
try {
// 获取本机IP地址并显示
ipLabel.setText("本机IP信息:" + InetAddress.getLocalHost().toString());
} catch (HeadlessException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
panel.add(ipLabel); // 添加IP地址标签到面板
panel.add(portLabel); // 添加端口号标签到面板
panel.add(portTextField); // 添加端口号输入框到面板
panel.add(listenButton); // 添加监听按钮到面板
panel.add(closeButton); // 添加关闭按钮到面板
add(panel, BorderLayout.NORTH); // 将面板添加到窗口北部
add(new JScrollPane(contentTextArea), BorderLayout.CENTER); // 将文本区域添加到窗口中央,可以滚动
add(inputTextField, BorderLayout.SOUTH); // 将输入框添加到窗口南部
listenButton.addActionListener(this); // 监听按钮添加事件监听器
closeButton.addActionListener(this); // 关闭按钮添加事件监听器
inputTextField.addActionListener(this); // 输入框添加事件监听器
addWindowListener(new WindowAdapter() { // 窗口关闭事件监听器,关闭程序时同时断开连接
@Override
public void windowClosing(WindowEvent e) {
disconnect();
}
});
setSize(500, 300); // 窗口大小
setLocationRelativeTo(null); // 将窗口位于屏幕的中央
setVisible(true); // 显示窗口
}
// 开始监听
public void start() {
try {
int port = Integer.parseInt(portTextField.getText()); // 获取输入的端口号
connected = true; // 标记已连接
ss = new ServerSocket(port); // 创建ServerSocket对象
s = ss.accept(); // 等待客户端连接
os = new DataOutputStream(s.getOutputStream()); // 创建输出流
is = new DataInputStream(s.getInputStream()); // 创建输入流
recvThread.start(); // 启动接收数据的线程
} catch (IOException e) {
} finally {
try {
ss.close(); // 关闭ServerSocket
} catch (IOException e) {
}
}
}
// 断开连接
public void disconnect() {
try {
if (os != null)
os.close(); // 关闭输出流
if (is != null)
is.close(); // 关闭输入流
if (s != null)
s.close(); // 关闭Socket
} catch (IOException e) {
}
System.exit(0); // 退出程序
}
// 使用内部类创建接收数据线程
private class RecvThread implements Runnable {
public void run() {
try {
while (connected) { // 如果连接上了
String str = is.readUTF(); // 接收客户端发送的数据
contentTextArea.setText(contentTextArea.getText() + "client:" + str + '\n'); // 在文本区域显示接收到的数据
}
} catch (EOFException e) { // 客户端关闭了连接
contentTextArea.setText("Client closed!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 事件处理函数
public void actionPerformed(ActionEvent e) {
// 如果按下的是监听按钮
if (e.getSource() == listenButton) {
listenButton.setEnabled(false); // 禁用监听按钮
start(); // 开始监听
} else if (e.getSource() == closeButton) { // 如果按下的是关闭按钮
disconnect(); // 断开连接
} else if (e.getSource() == inputTextField) { // 如果按下的是输入框回车键
String str = inputTextField.getText().trim(); // 获取输入框中的文本
inputTextField.setText(""); // 清空输入框
try {
os.writeUTF(str); // 发送数据给客户端
os.flush(); // 刷新输出流
contentTextArea.setText(contentTextArea.getText() + "server:" + str + '\n'); // 在文本区域显示发送的数据
} catch (IOException e1) {
}
}
}
// 主函数,创建窗口对象
public static void main(String[] args) {
new Server();
}
}
客户端程序代码注释(仅供参考)
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class Client extends JFrame implements ActionListener {
Socket s = null; // Socket对象
DataOutputStream os = null; // 输出流
DataInputStream is = null; // 输入流
private boolean connected = false; // 是否连接标志
JLabel ipLabel = new JLabel("IP"); // 显示IP地址的标签
JTextField ipTextField = new JTextField("127.0.0.1"); // IP地址输入框
JLabel portLabel = new JLabel("端口"); // 显示端口号的标签
JTextField portTextField = new JTextField("8000"); // 端口号输入框
JButton connectButton = new JButton("连接"); // 连接按钮
JButton closeButton = new JButton("关闭"); // 关闭按钮
JPanel panel = new JPanel(); // 包含各种控件的面板
JTextField inputTextField = new JTextField(); // 输入框
JTextArea contentTextArea = new JTextArea(); // 显示接收到的数据的文本区域
Thread recvThread = new Thread(new RecvThread()); // 接收数据的线程
// 构造函数
public Client() {
setTitle("客户端"); // 窗口标题
setLocation(400, 300); // 窗口位置
setSize(500, 500); // 窗口大小
setLayout(new BorderLayout()); // 设置布局为边界布局
panel.setLayout(new FlowLayout()); // 面板使用流式布局
panel.add(ipLabel); // 添加IP地址标签到面板
panel.add(ipTextField); // 添加IP地址输入框到面板
panel.add(portLabel); // 添加端口号标签到面板
panel.add(portTextField); // 添加端口号输入框到面板
panel.add(connectButton); // 添加连接按钮到面板
panel.add(closeButton); // 添加关闭按钮到面板
add(panel, BorderLayout.NORTH); // 将面板添加到窗口北部
add(new JScrollPane(contentTextArea), BorderLayout.CENTER); // 将文本区域添加到窗口中央,可以滚动
add(inputTextField, BorderLayout.SOUTH); // 将输入框添加到窗口南部
connectButton.addActionListener(this); // 连接按钮添加事件监听器
closeButton.addActionListener(this); // 关闭按钮添加事件监听器
inputTextField.addActionListener(this); // 输入框添加事件监听器
addWindowListener(new WindowAdapter() { // 窗口关闭事件监听器,关闭程序时同时断开连接
@Override
public void windowClosing(WindowEvent e) {
disconnect();
}
});
setSize(500, 300); // 窗口大小
setLocationRelativeTo(null); // 将窗口位于屏幕的中央
setVisible(true); // 显示窗口
}
// 连接服务器
public void connect() {
try {
String host, port;
host = ipTextField.getText(); // 获取输入的IP地址
port = portTextField.getText(); // 获取输入的端口号
s = new Socket(host, Integer.parseInt(port)); // 创建Socket对象并连接服务器
os = new DataOutputStream(s.getOutputStream()); // 创建输出流
is = new DataInputStream(s.getInputStream()); // 创建输入流
connected = true; // 标记已连接
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 断开连接
public void disconnect() {
try {
if (os != null)
os.close(); // 关闭输出流
if (is != null)
is.close(); // 关闭输入流
if (s != null)
s.close(); // 关闭Socket
} catch (IOException e) {
}
System.exit(0); // 退出程序
}
// 使用内部类创建接收数据线程
private class RecvThread implements Runnable {
public void run() {
try {
while (connected) { // 如果连接上了
String str = is.readUTF(); // 接收服务器发送的数据
contentTextArea.setText(contentTextArea.getText() + "server:" + str + '\n'); // 在文本区域显示接收到的数据
}
} catch (EOFException e) { // 服务器关闭了连接
contentTextArea.setText("Server closed!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 事件处理函数
public void actionPerformed(ActionEvent e) {
if (e.getSource() == connectButton) { // 如果按下的是连接按钮
connectButton.setEnabled(false); // 禁用连接按钮
connect(); // 连接服务器
recvThread.start(); // 启动接收数据的线程
} else if (e.getSource() == closeButton) { // 如果按下的是关闭按钮
disconnect(); // 断开连接
} else if (e.getSource() == inputTextField) { // 如果按下的是输入框回车键
String str = inputTextField.getText().trim(); // 获取输入框中的文本
inputTextField.setText(""); // 清空输入框
try {
os.writeUTF(str); // 发送数据给服务器
os.flush(); // 刷新输出流
contentTextArea.setText(contentTextArea.getText() + "client:" + str + '\n'); // 在文本区域显示发送的数据
} catch (IOException e1) {
}
}
}
// 主函数,创建窗口对象
public static void main(String[] args) {
new Client();
}
}
本文来自博客园,作者:Cloudservice,转载请注明原文链接:https://www.cnblogs.com/whwh/p/17844480.html,只要学不死,就往死里学!