Java套接字實現應用程式對資料庫的訪問

来源:https://www.cnblogs.com/jaydenchang/archive/2022/09/19/16707986.html
-Advertisement-
Play Games

最近在完成軟體體繫結構上機實驗時,遇到一個有點點小難度的選做題,題目信息如下: 利用套接字技術實現應用程式中對資料庫的訪問。應用程式只是利用套接字連接向伺服器發送一個查詢的條件,而伺服器負責對資料庫的查詢,然後伺服器再將查詢的結果利用建立的套接字返回給客戶端,如下圖所示。 本來吧,選做題,不太想做的 ...


最近在完成軟體體繫結構上機實驗時,遇到一個有點點小難度的選做題,題目信息如下:

利用套接字技術實現應用程式中對資料庫的訪問。應用程式只是利用套接字連接向伺服器發送一個查詢的條件,而伺服器負責對資料庫的查詢,然後伺服器再將查詢的結果利用建立的套接字返回給客戶端,如下圖所示。

本來吧,選做題,不太想做的,但是考慮到以後工作的方向和後端相關,那還是做吧。

本次實驗需要做一個GUI界面和一個連接查詢功能,在論壇上借鑒了其他大佬獲取網站內容的部分代碼,然後自己做了一個及其簡陋的swing界面,算是把這個實驗完成了。

本次實驗項目結構如下

--socketProject
    |--Client.java
    |--GUI.java
    |--SearchInfo.java
    |--Server.java
    |--ServerThread.java

Client.java

客戶端使用dis.readUTF()時,要註意再發送個字元或者空字元,這裡發送end,表示關閉連接。不然會出現EOFException

package socketProject;

import java.io.*;
import java.net.*;

public class Client {
    String studentNum = null;
    String result = null;

    public void setStudentNum(String num) {
        this.studentNum = num;
        System.out.println("stu: " + studentNum);
    }

    public void run() throws IOException {
        Socket ss = new Socket("127.0.0.1", 8888);
        System.out.println("Socket: " + ss);
        try {
            DataInputStream dis = new DataInputStream(ss.getInputStream());
            DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
            // the interaction
            dos.writeUTF(studentNum); // 向伺服器發送學號
            dos.flush();
            result = dis.readUTF().toString(); // 獲得客戶端的json字元串
            System.out.println(result);
            dos.writeUTF("end"); // 不加這句會報錯
            dos.flush();
            if (dos != null)
                dos.close();
            if (dis != null)
                dis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ss != null)
                ss.close();
        }
    }
	// gui界面用於獲取json結果
    public String getResult() {
        return result;
    }
}

Server.java

package socketProject;

import java.io.*;
import java.net.*;

public class Server extends Thread {
    public static final int PORT = 8888;

    // public static void main(String[] args) throws IOException {
    public void run() {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("ServerSocket: " + serverSocket);
            try {
                while (true) {
                    Socket socket = serverSocket.accept();
                    System.out.println("Socket accept: " + socket);
                    Thread thread = new Thread(new ServerThread(socket));
                    thread.start(); // 開啟一個線程,使之支持接收多個客戶端的請求
                }
            } finally {
                serverSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ServerThread.java

package socketProject;

import java.io.*;
import java.net.*;

public class ServerThread extends Thread {
    Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            while (true) {
                String str = dis.readUTF().toString();
                String data = new SearchInfo().run(str);
                if (str.equals("end"))
                    break;

                dos.writeUTF(data);
            }
            dos.close();
            dis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

SearchInfo.java

package socketProject;

import java.io.*;
import java.net.*;

public class SearchInfo {
    public String run(String s) {
        String url = "your database interface";
        String param = s;
        String sendGET = GetUrl(url, param);
        return sendGET;
    }
    
    public static String GetUrl(String url, String param) {
        String result = ""; // define the result str
        BufferedReader read = null; // define the access result
        
        try {
            URL realUrl = new URL(url + param);
            URLConnection connection = realUrl.openConnection();
            
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 這裡補充通用的請求屬性
            connection.connect(); // 建立實際的連接
            
            read = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = read.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (read != null) {// 關閉流
                try {
                    read.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    
    public String getJSON(String param) {
        return param;
    }
}

GUI.java

package socketProject;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;

public class GUI extends JFrame {
    private JButton connectDataBase;
    private JLabel entryStudentNum;
    private JTextField studentNum;
    private JButton sendRequest;
    private JLabel showResponseMsg;
    private JPanel northPanel;
    private JPanel southPanel;

    public GUI() {
        init();
    }

    public void init() {
        setTitle("沒啥技術含量的東西");
        // define the component for the window
        connectDataBase = new JButton("連接資料庫");
        entryStudentNum = new JLabel("輸入學號");
        studentNum = new JTextField();
        sendRequest = new JButton("發送");
        showResponseMsg = new JLabel();

        // add the component to the panel
        this.setLayout(new GridLayout(2, 1));

        northPanel = new JPanel(new GridLayout(1, 4));

        northPanel.add(connectDataBase);
        northPanel.add(entryStudentNum);
        northPanel.add(studentNum);
        northPanel.add(sendRequest);

        southPanel = new JPanel(new GridLayout(1, 1));

        southPanel.add(showResponseMsg);

        setButtons();

        this.add(northPanel);
        this.add(southPanel);
        // initial the window
        setBounds(400, 200, 600, 120);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void setButtons() {
        connectDataBase.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 這裡初始化服務端
                Server server1 = new Server();
                Thread th1 = new Thread(server1);
                th1.start();
                // 這裡一定要開啟服務端線程,否則在點擊此按鈕後,整個界面會卡住,無法進行下一步操作
            }
        });

        sendRequest.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Client client1 = new Client();
                client1.setStudentNum(studentNum.getText());
                // 獲取文本框的文字,並賦給客戶端的studentNum保存
                try {
                    client1.run();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                showResponseMsg.setText(client1.getResult());
                // 將得到的數據顯示在界面上
            }
        });
    }

    public static void main(String[] args) {
        new GUI();
    }
}

最終效果如下:

使用時,先點擊連接資料庫,然後根據學校提供的介面,輸入自己的學號,點擊發送,即可查詢個人信息。

不過由於項目工作區非maven以及未來方向非Java的緣故,沒有去深究如何提取json的值 (偷個懶)

參考鏈接

Java請求一個URL,獲取返回的數據_杜嵐特的博客-CSDN博客

java.io.datainputstream.readunsignedshort_socket編程報異常java.io.EOFException_竇月汐的博客-CSDN博客


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我的JSP&Servlet之旅。本節複習鞏固HTTP基礎知識,涉及URI編碼,Servlet &JSP的運作方式,Web開發模式架構。 ...
  • 【原文地址:https://xiaokang2022.blog.csdn.net/article/details/126936985】 ​ 一個不會寫好的類型標註和註釋的Python程式員,是讓使用TA的代碼的人都痛苦無比的事情…… —— 某某大佬 一、代碼智能感知 想必大部分現代的集成開發環境(I ...
  • Arrays類 Arrays裡面包含了一系列靜態方法,用於管理或操作數組(比如排序和搜索) 常用方法 toString 返回數組的字元串形式 Arrays.toString(arr) Integer[] integers = {1, 20, 90}; System.out.println(Array ...
  • 前言 本人最近幾年一直在學習並且實踐雲原生,也從測試轉型到DevOps,公司的所有服務也從數據中心搬到雲端,回顧過去幾年學到的知識,覺得是時候總結一下了,所以準備以雲原生為題材寫下這一過程中所有學到的知識點,希望對大家有所幫助。 在我帶你開始雲原生之旅前,需要入門一下golang,沒辦法,誰讓它是雲 ...
  • 今天帶大家一起來看看網上流傳關於程式員的經典硬核段子,快來看看你是否能get到笑點。 白嫖福利,傳送門 段子1 昨天晚上下班回家,一民警迎面巡邏而來。突然對我大喊:站住! 民警:int 類型占幾個位元組? 我:4 個。 民警:你可以走了。 我感到很詫異。 我:為什麼問這樣的問題? 民警:深夜還在街上走 ...
  • 前言 準備工作 步驟 1 配置fiddler和WX環境 fiddler配置 其他的照我截的圖片配置就好 這樣 fiddler 就配置好,是不是很簡單 WX配置 配置代理 註:埠號得和fiddler配置的一致,也就是這個位置 至於ip地址,使用這個即可 黑框調出方式:win+R,輸入cmd然後回車, ...
  • 我們先瞭解下Servlet的生命周期 Servlet部署在容器里,其生命周期由容器管理。 概括為以下幾個階段: 1)容器載入Servlet類。 當第一次有Web客戶請求Servlet服務或當Web服務啟動時。 2)創建Servlet對象實例。 容器環境根據客戶請求,創建一個或多個Servlet對象實 ...
  • 1 耳返功能簡介 ZEGO Express SDK 提供了Flutter耳返和雙聲道的功能,在視頻直播、K歌、音頻錄製等場景下廣泛應用,開發者可根據實際業務場景需要設置,一套代碼可實現跨平臺音視頻耳返功能,節省開發成本。 實時音視頻的耳返作用就是在嘈雜的環境下,清楚地聽伴奏和自己的聲音,來鑒定自己有 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...