项目结构目录
服务端代码
package cn.itcast.chat;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerChat extends JFrame implements ActionListener,KeyListener {
//在启动的时候创建窗体
public static void main(String[] args) {
new ServerChat();
}
//属性
//文本域
private JTextArea jta;
//滚动条
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框(发送框)
private JTextField jtf;
//按钮
private JButton jb;
//输出流
private BufferedWriter bw =null;
//从配置文件中读取服务端端口号
private static int serverPort;
//使用静态代码块进行加载配置文件,并初始化serverPort
//静态代码块:类加载的时候执行,只执行一次
static{
Properties prop = new Properties();
try {
prop.load(new FileReader("chat.properties"));
serverPort = Integer.parseInt(prop.getProperty("serverPort"));
}catch (Exception e) {
e.printStackTrace();
}
}
//在构造方法中初始化组件
public ServerChat(){
//初始化组件
//设置文本域默认不可编辑
jta=new JTextArea();
jta.setEditable(false);
//将文本域加入到滚动条中
jsp=new JScrollPane(jta);
jp = new JPanel();
jtf=new JTextField(10);
jb=new JButton("发送");
//将文本框与按钮添加到面板中
jp.add(jtf);
jp.add(jb);
//将滚动条和面板添加到窗体中,this代表当前窗体
this.add(jsp,BorderLayout.CENTER);
this.add(jp,BorderLayout.SOUTH);
//设置窗体的一些样式
this.setTitle("QQ聊天服务端");
this.setSize(400, 400);
this.setLocation(200, 200);
//窗体关闭的时候 ,程序就退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
/*********************TCP 服务端 start*********************/
//给发送按钮添加监听点击事件
jb.addActionListener(this);
//给文本框添加键盘监听事件
jtf.addKeyListener(this);
try {
//1、创建一个服务端Socket套接字
ServerSocket serverSocket = new ServerSocket(serverPort);
//2、等待客户端连接
Socket socket = serverSocket.accept();
//3、获取Socket通道的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//4、获取Socket通道的输出流(当点击发送的时候才需要输出数据)
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//循环读取数据,并进行拼接
String line=null;
while((line=br.readLine())!=null){
//将读取到的数据拼接在文本域中显示,并且换行
jta.append(line+System.lineSeparator());
}
//5、关闭ServerSocket通道
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*********************TCP 服务端 end*********************/
}
@Override
public void actionPerformed(ActionEvent e) {
sendMsg();
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_ENTER){
sendMsg();
}
}
//定义一个方法,让其向Socket通道中发送数据
public void sendMsg(){
//1、获取文本框中发送的内容
String text = jtf.getText();
//2、拼接需要发送的内容给你
text = "客户端对服务端说:"+text;
//3、自己也需要显示,这里需要加换行,
//没有在上面第二步的时候加,是因为加了以后会把换行也会发送出去,bw不能正确读取
jta.append(text+System.lineSeparator());
//发送
try {
bw.write(text);
//换行并刷新,否则对方收不到
bw.newLine();
bw.flush();
//清空文本框
jtf.setText(" ");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
客户端代码
package cn.itcast.chat;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 1、定义JFrame窗口中的组件
* 2、在构造方法中初始化这些组件
* 3、使用网络编程完成数据的传输
* 4、实现‘发送’按钮的监听点击事件
* 5、使用回车键发送数据(给文本框添加键盘监听事件)
*/
public class ClientChat extends JFrame implements ActionListener,KeyListener{
//在启动的时候创建窗体
public static void main(String[] args) {
new ClientChat();
}
//属性
//文本域
private JTextArea jta;
//滚动条
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框(发送框)
private JTextField jtf;
//按钮
private JButton jb;
//从配置文件中读取客户端IP以及端口号
private static String clientIP;
private static int clientPort;
//使用静态代码块进行加载配置文件,并初始化serverPort
//静态代码块:类加载的时候执行,只执行一次
static{
Properties prop = new Properties();
try {
prop.load(new FileReader("chat.properties"));
clientIP = prop.getProperty("clientIP");
clientPort = Integer.parseInt(prop.getProperty("clientPort"));
}catch (Exception e) {
e.printStackTrace();
}
}
//输出流
private BufferedWriter bw = null;
//在构造方法中初始化组件
public ClientChat(){
//初始化组件
//设置文本域默认不可编辑
jta=new JTextArea();
jta.setEditable(false);
//将文本域加入到滚动条中
jsp=new JScrollPane(jta);
jp = new JPanel();
jtf=new JTextField(10);
jb=new JButton("发送");
//将文本框与按钮添加到面板中
jp.add(jtf);
jp.add(jb);
//将滚动条和面板添加到窗体中,this代表当前窗体
this.add(jsp,BorderLayout.CENTER);
this.add(jp,BorderLayout.SOUTH);
//设置窗体的一些样式
this.setTitle("QQ聊天服务端");
this.setSize(400, 400);
this.setLocation(600, 200);
//窗体关闭的时候 ,程序就退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
/*********************TCP 客户端 start*********************/
//给发送按钮添加一个监听点击事件(该类需要实现ActionListener接口)
jb.addActionListener(this);
//给文本框添加监听键盘事件(该类实现KeyListener接口)
jtf.addKeyListener(this);
try {
//1、创建一个客户端Socket套接字(尝试连接)
Socket socket = new Socket(clientIP,clientPort);
//2、获取Socket通道的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//3、获取Socket通道的输出流(当点击发送的时候才需要输出数据)
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//循环读取数据,并进行拼接
String line=null;
while((line=br.readLine())!=null){
//将读取到的数据拼接在文本域中显示,并且换行
jta.append(line+System.lineSeparator());
}
//4、关闭Socket通道
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*********************TCP 服务端 end*********************/
}
@Override
public void actionPerformed(ActionEvent e) {
sendMsg();
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_ENTER){
sendMsg();
}
}
//定义一个方法,让其向Socket通道中发送数据
public void sendMsg(){
//1、获取文本框中发送的内容
String text = jtf.getText();
//2、拼接需要发送的内容给你
text = "客户端对服务端说:"+text;
//3、自己也需要显示,这里需要加换行,
//没有在上面第二步的时候加,是因为加了以后会把换行也会发送出去,bw不能正确读取
jta.append(text+System.lineSeparator());
//发送
try {
bw.write(text);
//换行并刷新,否则对方收不到
bw.newLine();
bw.flush();
//清空文本框
jtf.setText(" ");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
打包脱离eclipse
首先将ServerChat.java,ClientChat.java分别打包,右击—>export—–>搜索JAR file——>填写导出地址——>next——>next——->填写main class.——–>finish
将配置文件与导出的jar包放在同一目录,使用命令提示符运行,即可。
先启动服务端,后启动客户端
//启动服务端
C:\Users\lenovo>cd /d C:\Users\lenovo\Desktop
C:\Users\lenovo\Desktop>java -jar server.jar
//启动客户端
C:\Users\lenovo>cd /d C:\Users\lenovo\Desktop
C:\Users\lenovo\Desktop>java -jar client.jar