一、如何实现TCP通信
要实现TCP通信需要创建一个服务器端程序和一个客户端程序,为了保证数据传输的安全性,首先需要实现服务器端程序,然后在编写客户端程序。
在本机运行服务器端程序,在远程机运行客户端程序
本机的IP地址:192.168.129.222
远程机的IP地址:192.168.214.213
二、编写C/S架构聊天程序
1.编写服务器端程序 - Server.java
在net.hw.network包里创建Server类
package net.hw.network;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends JFrame {
static final int PORT = 8136;
static final String HOST_IP = "192.168.129.222";
private JPanel panel1, panel2;
private JTextArea txtContent, txtInput, txtInputIP;
private JScrollPane panContent, panInput;
private JButton btnClose, btnSend;
private ServerSocket serverSocket;
private Socket socket;
private DataInputStream netIn;
private DataOutputStream netOut;
public static void main(String[] args) {
new Server();
}
public Server() {
super("服务器");
//创建组件
panel1 = new JPanel();
panel2 = new JPanel();
txtContent = new JTextArea(15, 60);
txtInput = new JTextArea(3, 60);
panContent = new JScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
panInput = new JScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
btnClose = new JButton("关闭");
btnSend = new JButton("发送");
//添加组件
getContentPane().add(panContent, "Center");
getContentPane().add(panel1, "South");
panel1.setLayout(new GridLayout(0, 1));
panel1.add(panInput);
panel1.add(panel2);
panel2.add(btnSend);
panel2.add(btnClose);
//设置组件属性
txtContent.setEditable(false);
txtContent.setFont(new Font("宋体", Font.PLAIN, 13));
txtInput.setFont(new Font("宋体", Font.PLAIN, 15));
txtContent.setLineWrap(true);
txtInput.setLineWrap(true);
txtInput.requestFocus();
setSize(450, 350);
setLocation(50, 200);
setResizable(false);
setVisible(true);
//等候客户请求
try {
txtContent.append("服务器已启动...\n");
serverSocket = new ServerSocket(PORT);
txtContent.append("等待客户请求...\n");
socket = serverSocket.accept();
txtContent.append("连接一个客户。\n" + socket + "\n");
netIn = new DataInputStream(socket.getInputStream());
netOut = new DataOutputStream(socket.getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
/
//注册监听器,编写事件代码
txtContent.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayClientMsg();
}
});
txtInput.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayClientMsg();
}
});
panel2.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayClientMsg();
}
});
txtInput.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
displayClientMsg();
}
});
txtInput.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
displayClientMsg();
}
});
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String serverMsg = txtInput.getText();
if (!serverMsg.trim().equals("")) {
txtContent.append("服务器>" + serverMsg + "\n");
netOut.writeUTF(serverMsg);
} else {
JOptionPane.showMessageDialog(null, "不能发送空信息!", "服务器", JOptionPane.WARNING_MESSAGE);
}
txtInput.setText("");
txtInput.requestFocus();
} catch (IOException ie) {
ie.printStackTrace();
}
}
});
btnClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
netIn.close();
netOut.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
netIn.close();
netOut.close();
socket.close();
serverSocket.close();
} catch (IOException ie) {
ie.printStackTrace();
}
System.exit(0);
}
public void windowActivated(WindowEvent e) {
txtInput.requestFocus();
}
});
}
//显示客户端信息
void displayClientMsg() {
try {
if (netIn.available() > 0) {
String clientMsg = netIn.readUTF();
txtContent.append("客户端>" + clientMsg + "\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
2.编写客户端程序 - Client.java
在net.hw.network包里创建Client类
package net.hw.network;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class Client extends JFrame {
private JPanel panel1, panel2;
private JTextArea txtContent, txtInput;
private JScrollPane panContent, panInput;
private JButton btnClose, btnSend;
private Socket socket;
private DataInputStream netIn;
private DataOutputStream netOut;
public static void main(String[] args) {
new Client();
}
public Client() {
super("客户端");
//创建组件
panel1 = new JPanel();
panel2 = new JPanel();
txtContent = new JTextArea(15, 60);
txtInput = new JTextArea(3, 60);
panContent = new JScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
panInput = new JScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
btnClose = new JButton("关闭");
btnSend = new JButton("发送");
//添加组件
getContentPane().add(panContent, "Center");
getContentPane().add(panel1, "South");
panel1.setLayout(new GridLayout(0, 1));
panel1.add(panInput);
panel1.add(panel2);
panel2.add(btnSend);
panel2.add(btnClose);
//设置组件属性
txtContent.setEditable(false);
txtContent.setFont(new Font("宋体", Font.PLAIN, 13));
txtInput.setFont(new Font("宋体", Font.PLAIN, 15));
txtContent.setLineWrap(true);
txtInput.setLineWrap(true);
txtInput.requestFocus();
setSize(450, 350);
setLocation(550, 200);
setResizable(false);
setVisible(true);
//连接服务器
try {
txtContent.append("连接服务器...\n");
socket = new Socket(Server.HOST_IP, Server.PORT);
txtContent.append("连接服务器成功。\n" + socket + "\n");
netIn = new DataInputStream(socket.getInputStream());
netOut = new DataOutputStream(socket.getOutputStream());
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "服务器连接失败!\n请先启动服务器程序!", "客户端", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
/
//注册监听器,编写事件代码
txtContent.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayServerMsg();
}
});
txtInput.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayServerMsg();
}
});
panel2.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
displayServerMsg();
}
});
txtInput.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
displayServerMsg();
}
});
txtInput.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
displayServerMsg();
}
});
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String clientMsg = txtInput.getText();
if (!clientMsg.trim().equals("")) {
netOut.writeUTF(clientMsg);
txtContent.append("客户端>" + clientMsg + "\n");
} else {
JOptionPane.showMessageDialog(null, "不能发送空信息!", "客户端", JOptionPane.WARNING_MESSAGE);
}
txtInput.setText("");
txtInput.requestFocus();
} catch (IOException ie) {
ie.printStackTrace();
}
}
});
btnClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
netIn.close();
netOut.close();
socket.close();
} catch (IOException ie) {
ie.printStackTrace();
}
System.exit(0);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
netIn.close();
netOut.close();
socket.close();
} catch (IOException ie) {
ie.printStackTrace();
}
System.exit(0);
}
public void windowActivated(WindowEvent e) {
txtInput.requestFocus();
}
});
}
//显示服务端信息
void displayServerMsg() {
try {
if (netIn.available() > 0) {
String serverMsg = netIn.readUTF();
txtContent.append("服务器>" + serverMsg + "\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
3.测试服务器端与客户端能否通信
在本机[192.168.129.222]上启动服务器端
在远程机[192.168.214.213]上启动客户端
显示连接服务器[192.168.129.222]成功,切换到服务器端查看,显示连接了一个客户[192.168.214.213]
此时,服务器端和客户端就可以相互通信了
4.程序优化思路 - 服务器端采用多线程
其实,很多服务器端程序都是允许被多个应用程序访问的,例如门户网站可以被多个用户同时访问,因此服务器端都是多线程的。
以上就是Java实战之基于TCP实现简单聊天程序的详细内容,更多关于Java TCP聊天程序的资料请关注编程网其它相关文章!