实现一对具有聊天功能的客户端与服务端 如图:
一、总步骤
1.建立网络连接
2.通过管道传输信息
3.增加一个图形化界面
4.在图形化界面上添加动作监听器
5.在客户端/服务端添加收发信息功能
注意事项:先启用服务端,然后开启客户端
二、详细过程
2.1建立网络连接
服务端通过Socket连接客户端,分为三步
1.服务端监听
2.客户端请求
3.确认连接
1.创建一个端口号为8888,IP地址为本机地址的socket
ServerSocket serverSocket = new ServerSocket(8888);
2.进入监听状态
Socket client = serverSocket.accept();
3.确认连接(创建一个新的客户端类,在新类中写)
Socket socket = new Socket("127.0.0.1", 8888);
2.2.通过管道传输信息
管道的特点是,通过输入流接受其他类处理的结果,加工后通过输出流传出
1.在服务端创建输入输出流
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
2.在客户端创建输出输出流
2.3.增加一个图形化界面
建立图形化界面分为
1.建立窗体,添加文本框
2.添加发送消息按钮
1.建立窗体,添加文本框 先获取输入输出流,并设置窗体类的构造方法
创建MsgUI类
为了实现文本传输,需要传递outputStream对象,将文本框jTextPane1中的文字传入outputStream对象中,返回jTextPane用于显示文字
OutputStream outputStream;
MsgUI(OutputStream outputStream) {
this.outputStream = outputStream;
}
当MsgUI被调用时,执行initUI方法,建立一个图形化界面
public JTextPane initUI(String title) {
setTitle(title);
setSize(800, 600);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // 在*
setLayout(new FlowLayout());
//添加一个两个文本框,一个用于读入输入的信息,另一个用于接受消息
JTextPane jTextPane = new JTextPane();
jTextPane.setPreferredSize(new Dimension(200, 200));
JScrollPane jScrollPane = new JScrollPane(jTextPane);
JTextPane jTextPane1 = new JTextPane();
jTextPane1.setPreferredSize(new Dimension(200, 200));
JScrollPane jScrollPane1 = new JScrollPane(jTextPane1);
add(jScrollPane);
add(jScrollPane1);
setVisible(true);
return jTextPane;
}
2.添加消息发送按钮
JButton jButton = new JButton("send");
add(jButton);
2.4.在图形化界面上添加动作监听器
为按钮绑定动作监听器,实现读入文本,点击按钮发送的功能
在initUI方法中为按钮绑定监听器,当监听器调用时用文本框中的文字修改outputStream中的文本
MsgListener msgListener = new MsgListener(jTextPane1, this.outputStream);
jButton.addActionListener(msgListener);
创建MsgListener类,含有outoutStream和jTextPane两个参数
public class MsgListener implements ActionListener{
JTextPane jTextPane;
OutputStream outputStream;
MsgListener(JTextPane jTextPane, OutputStream outputStream) {
this.outputStream = outputStream;
this.jTextPane = jTextPane;
}
实现抽象方法,当按钮按下时传输文本
public void actionPerformed(ActionEvent e) {
try {
String message = jTextPane.getText();
byte[] messages = message.getBytes();
outputStream.write(messages.length);
outputStream.write(jTextPane.getText().getBytes());
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
2.5 在客户端/服务端中调用添加消息收发功能
以客户端为例: 1.实例化窗体
MsgUI msgUI = new MsgUI(outputStream);
JTextPane messagePane = msgUI.initUI("client");
2.读入从inputStream获得的信息,转为文字显示在窗体上
while (true) {
//传入地址,构造字节数组
int msgLength = inputStream.read();
byte[] msgBytes = new byte[120];
//读入文本
inputStream.read(msgBytes);
//构造字符串,接受字符数组的信息
String getMessage = new String(msgBytes);
//缓存文本框中的文字,从而连续收发消息
String msg = messagePane.getText();
messagePane.setText(msg + "server say: " + getMessage + "\n");
三、源代码
客户端
package Server2;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class MsgClient {
public static void main(String[] args) throws IOException {
Socket serverSocket = new Socket("127.0.0.1", 8888);
// 输入输出流对象
InputStream inputStream = serverSocket.getInputStream();
OutputStream outputStream = serverSocket.getOutputStream();
MsgUI msgUI = new MsgUI(outputStream);
JTextPane messagePane = msgUI.initUI("client");
while (true) {
//传入地址,构造字节数组
int msgLength = inputStream.read();
byte[] msgBytes = new byte[120];
//读入
inputStream.read(msgBytes);
String getMessage = new String(msgBytes);
// System.out.println("来自服务器的消息:" + "长度为:" + msgLength + " " + getMessage);
String msg = messagePane.getText();
messagePane.setText(msg + "server say: " + getMessage + "\n");
}
监听器
package Server2;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.OutputStream;
public class MsgListener implements ActionListener {
JTextPane jTextPane;
OutputStream outputStream;
MsgListener(JTextPane jTextPane, OutputStream outputStream) {
this.outputStream = outputStream;
this.jTextPane = jTextPane;
}
@Override
public void actionPerformed(ActionEvent e) {
try {
String message = jTextPane.getText();
byte[] messages = message.getBytes();
outputStream.write(messages.length);
outputStream.write(jTextPane.getText().getBytes());
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
服务端
package Server2;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MsgServer {
public static void main(String args[]) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888); //推荐使用5000+端口,防冲突
Socket client = serverSocket.accept(); //监听连接
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
MsgUI msgUI = new MsgUI(outputStream);
JTextPane messagePane = msgUI.initUI("server");
while (true) {
int msgLength = inputStream.read();
System.out.println("message length is " + msgLength);
byte[] msgBytes = new byte[msgLength];
inputStream.read(msgBytes);
String getMsg = new String(msgBytes);
System.out.println("client say: " + getMsg);
String msg = messagePane.getText();
messagePane.setText(msg + "client say: " + getMsg + "\n");
}
}
}
图形界面
package Server2;
import javax.swing.*;
import java.awt.*;
import java.io.OutputStream;
public class MsgUI extends JFrame {
OutputStream outputStream;
Graphics graphics;
MsgUI(OutputStream outputStream) {
this.outputStream = outputStream;
}
public JTextPane initUI(String title) {
setTitle(title);
setSize(800, 600);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // 在*
setLayout(new FlowLayout());
JTextPane jTextPane = new JTextPane();
jTextPane.setPreferredSize(new Dimension(200, 200));
JScrollPane jScrollPane = new JScrollPane(jTextPane);
JTextPane jTextPane1 = new JTextPane();
jTextPane1.setPreferredSize(new Dimension(200, 200));
JScrollPane jScrollPane1 = new JScrollPane(jTextPane1);
JButton jButton = new JButton("send");
add(jScrollPane);
add(jScrollPane1);
add(jButton);
setVisible(true);
graphics = getGraphics();
MsgListener msgListener = new MsgListener(jTextPane1, this.outputStream);
jButton.addActionListener(msgListener);
return jTextPane;
}
}