首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

基於java TCP網絡通信的實例詳解

     編輯:Java 程式設計入門

Java TCP網絡通信完整實例:Server與Client雙向交互

Java網絡編程主要有TCP(可靠流式)和UDP(數據報)兩種模式。TCP保證數據順序、無丟失,連接斷開雙向結束;UDP效率高但可能丟包、亂序。本文提供基於Swing界面的TCP Server/Client完整代碼。

Server端核心代碼

package TCP;
import java.io.*; import java.net.*; import javax.swing.*;

public class Server {
    static BufferedReader br; static PrintStream ps; static JTextArea text;
    JFrame frame;

    public Server() {
        frame = new JFrame("服務器端");
        text = new JTextArea(); text.setEditable(false);
        frame.add(new JScrollPane(text));
        frame.setSize(300,400); frame.setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        new Server();
        ServerSocket server = new ServerSocket(2000);
        text.append("監聽2000端口\n");
        Socket client = server.accept(); // 阻塞等待連接
        br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        ps = new PrintStream(client.getOutputStream());

        String msg;
        while ((msg = br.readLine()) != null) {
            text.append("服務器端收到:" + msg + "\n");
            ps.println(msg); // 回傳確認
            if (msg.equals("quit")) {
                text.append("客戶端已退出!\n服務器程序將退出!");
                break;
            }
        }
        ps.close(); br.close(); client.close();
    }
}

Client端核心代碼

package TCP;
import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import java.net.*;

public class Client implements ActionListener {
    // 連接界面組件
    JFrame frame; JTextField adresstext, porttext; JButton connect;
    // 通信界面組件
    JFrame frame1; JTextArea shurukuang; TextArea jieshoukuang; JButton send;
    // 網絡流
    static BufferedReader br1; static PrintStream ps; static BufferedReader br2;
    static Socket client; static ByteArrayInputStream stringInputStream;

    public Client() {
        // 初始化連接界面
        frame = new JFrame(); frame.setLayout(new FlowLayout());
        adresstext = new JTextField("127.0.0.1",10);
        porttext = new JTextField("2000",10);
        connect = new JButton("連接"); connect.addActionListener(this);
        frame.add(new JLabel("IP地址")); frame.add(adresstext);
        frame.add(new JLabel("端口號")); frame.add(porttext); frame.add(connect);
        frame.setSize(200,150); frame.setVisible(true);

        // 初始化通信界面(初始隱藏)
        frame1 = new JFrame(); frame1.setLayout(new FlowLayout());
        shurukuang = new JTextArea("請輸入····",5,40);
        jieshoukuang = new TextArea(8,60); jieshoukuang.setEditable(false);
        send = new JButton("發送"); send.addActionListener(this);
        frame1.add(new JLabel("請輸入")); frame1.add(shurukuang);
        frame1.add(send);
        frame1.add(new JLabel("已接受")); frame1.add(jieshoukuang);
        frame1.setSize(500,350); frame1.setVisible(false);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == connect) {
            try {
                client = new Socket("127.0.0.1", 2000);
                frame.setVisible(false); frame1.setVisible(true);
                br1 = new BufferedReader(new InputStreamReader(client.getInputStream()));
                ps = new PrintStream(client.getOutputStream());
                jieshoukuang.append("已經連接上服務器!\n");
            } catch (IOException ex) { ex.printStackTrace(); }
        }
        if (e.getSource() == send) {
            try {
                stringInputStream = new ByteArrayInputStream(shurukuang.getText().getBytes());
                br2 = new BufferedReader(new InputStreamReader(stringInputStream));
                String msg;
                while ((msg = br2.readLine()) != null) {
                    ps.println(msg);
                    jieshoukuang.append("向服務器發送:" + msg + "\n");
                    jieshoukuang.append("客戶端接受響應:" + br1.readLine() + "\n");
                    if (msg.equals("quit")) { /* 關閉資源、隱藏窗口 */ break; }
                }
                shurukuang.setText("");
            } catch (IOException ex) { ex.printStackTrace(); }
        }
    }

    public static void main(String[] args) throws IOException {
        new Client(); // 顯示連接界面
        // 注意:這裡重複創建Socket會導致邏輯錯誤,實際應在connect事件中初始化流
    }
}

常見疑問解析

  1. main為何必須static? JVM啟動時無實例,需靜態入口方法。
  2. BufferedReader為何不能直接判斷? readLine()返回字符串或null,需賦值給變量才能多次使用(如判斷null與打印)。
  3. 按鈕事件與main中重複創建Socket導致NullPointerException? main中提前創建client但未初始化流,事件中又創建新client,導致br1/ps引用混亂。正確做法:僅在連接成功後在事件處理器中初始化Socket及流,main僅啟動UI。

代碼演示了TCP通信的基本流程,實際項目中應加入線程處理並發、異常恢復、協議設計等健壯性措施。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved