Java實戰(zhàn)之基于TCP實現(xiàn)簡單聊天程序
一、如何實現(xiàn)TCP通信
要實現(xiàn)TCP通信需要創(chuàng)建一個服務(wù)器端程序和一個客戶端程序,為了保證數(shù)據(jù)傳輸?shù)陌踩裕紫刃枰獙崿F(xiàn)服務(wù)器端程序,然后在編寫客戶端程序。
在本機(jī)運行服務(wù)器端程序,在遠(yuǎn)程機(jī)運行客戶端程序
本機(jī)的IP地址:192.168.129.222

遠(yuǎn)程機(jī)的IP地址:192.168.214.213

二、編寫C/S架構(gòu)聊天程序
1.編寫服務(wù)器端程序 - Server.java
在net.hw.network包里創(chuàng)建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;
/**
* 功能:服務(wù)器端
* 作者:華衛(wèi)
* 日期:2022年03月18日
*/
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("服務(wù)器");
//創(chuàng)建組件
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("關(guān)閉");
btnSend = new JButton("發(fā)送");
//添加組件
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);
//設(shè)置組件屬性
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("服務(wù)器已啟動...\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();
}
/
//注冊監(jiān)聽器,編寫事件代碼
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("服務(wù)器>" + serverMsg + "\n");
netOut.writeUTF(serverMsg);
} else {
JOptionPane.showMessageDialog(null, "不能發(fā)送空信息!", "服務(wù)器", 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包里創(chuàng)建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;
/**
* 功能:客戶端
* 作者:華衛(wèi)
* 日期:2022年03月18日
*/
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("客戶端");
//創(chuàng)建組件
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("關(guān)閉");
btnSend = new JButton("發(fā)送");
//添加組件
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);
//設(shè)置組件屬性
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);
//連接服務(wù)器
try {
txtContent.append("連接服務(wù)器...\n");
socket = new Socket(Server.HOST_IP, Server.PORT);
txtContent.append("連接服務(wù)器成功。\n" + socket + "\n");
netIn = new DataInputStream(socket.getInputStream());
netOut = new DataOutputStream(socket.getOutputStream());
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "服務(wù)器連接失??!\n請先啟動服務(wù)器程序!", "客戶端", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
/
//注冊監(jiān)聽器,編寫事件代碼
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, "不能發(fā)送空信息!", "客戶端", 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();
}
});
}
//顯示服務(wù)端信息
void displayServerMsg() {
try {
if (netIn.available() > 0) {
String serverMsg = netIn.readUTF();
txtContent.append("服務(wù)器>" + serverMsg + "\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
3.測試服務(wù)器端與客戶端能否通信
在本機(jī)[192.168.129.222]上啟動服務(wù)器端

在遠(yuǎn)程機(jī)[192.168.214.213]上啟動客戶端

顯示連接服務(wù)器[192.168.129.222]成功,切換到服務(wù)器端查看,顯示連接了一個客戶[192.168.214.213]

此時,服務(wù)器端和客戶端就可以相互通信了

4.程序優(yōu)化思路 - 服務(wù)器端采用多線程
其實,很多服務(wù)器端程序都是允許被多個應(yīng)用程序訪問的,例如門戶網(wǎng)站可以被多個用戶同時訪問,因此服務(wù)器端都是多線程的。

以上就是Java實戰(zhàn)之基于TCP實現(xiàn)簡單聊天程序的詳細(xì)內(nèi)容,更多關(guān)于Java TCP聊天程序的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot上傳圖片到指定位置并返回URL的實現(xiàn)
本文主要介紹了SpringBoot上傳圖片到指定位置并返回URL,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下<BR>2022-03-03
Java集合定義與用法實例總結(jié)【Set、List與Map】
這篇文章主要介紹了Java集合定義與用法,結(jié)合實例形式總結(jié)分析了Java集合中Set、List和Map相關(guān)概念、功能、用法及操作注意事項,需要的朋友可以參考下2018-08-08
MyBatis游標(biāo)Cursor的正確使用和百萬數(shù)據(jù)傳輸?shù)膬?nèi)存測試

