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-03Java集合定義與用法實例總結(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)存測試