国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java中的socket

Ajian / 2043人閱讀

摘要:服務(wù)器端線程實(shí)現(xiàn)首先將服務(wù)器獨(dú)立成一個(gè)線程服務(wù)器線程接受客戶端連接請(qǐng)求在構(gòu)造函數(shù)中我們初始化服務(wù)器的,然后等待客戶端的連接。

這次在java實(shí)驗(yàn)的時(shí)候,要求使用server socket編寫(xiě)服務(wù)器和客戶端的網(wǎng)絡(luò)通信。最開(kāi)始認(rèn)為應(yīng)該是挺簡(jiǎn)單的,但是后來(lái)發(fā)現(xiàn)低估了它。出現(xiàn)了不少的問(wèn)題,所以也在這里與大家分享。

問(wèn)題描述
服務(wù)器程序的處理規(guī)則如下:
1) 向客戶端程序發(fā)送Verifying Server!。
2) 若讀口令次數(shù)超過(guò)3次,則發(fā)送Illegal User!給客戶端,程序退出。否則向下執(zhí)行步驟3)。
3) 讀取客戶端程序提供的口令。
4) 若口令不正確,則發(fā)送PassWord Wrong!給客戶端,并轉(zhuǎn)步驟2),否則向下執(zhí)行步驟5)。
5) 發(fā)送Registration Successful!給客戶端程序。

客戶端程序的處理規(guī)則如下:
1) 讀取服務(wù)器反饋信息。
2) 若反饋信息不是Verifying Server!,則提示Server Wrong!,程序退出。否則向下執(zhí)行步驟3)
3) 提示輸入PassWord并將輸入的口令發(fā)送給服務(wù)器。
4) 讀取服務(wù)器反饋信息。
5) 若反饋信息是Illegal User!,則提示Illegal User!,程序退出。否則向下執(zhí)行步驟6)
6) 若反饋信息是PassWord Wrong!,則提示PassWord Wrong!,并轉(zhuǎn)步驟3),否則向下執(zhí)行步驟。
7) 輸出Registration Successful!。

初步實(shí)現(xiàn)

首先,我們一定要清楚,這次和之前的程序不同,雖然都是在本地上,但是服務(wù)器客戶端需要兩個(gè)啟動(dòng)程序來(lái)實(shí)現(xiàn),以達(dá)到我們模擬遠(yuǎn)程連接的效果。

然后就是如何利用socket實(shí)現(xiàn)我們的功能了。

通過(guò)上面的圖示,我們可以知道,首先需要先開(kāi)啟服務(wù)器,然后等待客戶端的連接。

當(dāng)客戶端通過(guò)socket進(jìn)行連接后,服務(wù)器端也會(huì)建立一個(gè)socket對(duì)象來(lái)幫助實(shí)現(xiàn)服務(wù)器和客戶端的通信。

這時(shí)候就建立了一個(gè)TCP連接,我們就可以在服務(wù)器寫(xiě)數(shù)據(jù),然后在客戶端讀取了,實(shí)現(xiàn)雙方通信。

最后,當(dāng)有一方?jīng)Q定通信結(jié)束,就會(huì)關(guān)閉連接。通信結(jié)束。

下面是初步實(shí)現(xiàn)的代碼:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服務(wù)器
 */
public class ServerTest {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            Socket clientSocket = serverSocket.accept();

            String welcome  = "verifying server!";
            OutputStream outputStream = clientSocket.getOutputStream();
            outputStream.write(welcome.getBytes());

            InputStream inputStream = clientSocket.getInputStream();
            int time = 0;

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String password = bufferedReader.readLine();

            // 獲取登錄信息,允許3次登錄
            while (time < 3) {
                if (password.equals("123")) {
                    outputStream.flush();
                    outputStream.write("Registration Successful!".getBytes());
                    break;
                } else {
                    outputStream.write("PassWord Wrong!".getBytes());
                    outputStream.flush();
                    password = bufferedReader.readLine();
                    time++;
                }
            }

            if (time >= 3) {
                outputStream.flush();
                outputStream.write("Illegal User!".getBytes());
            }

            outputStream.close();
            clientSocket.close();
            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.*;
import java.net.Socket;

/**
 * 客戶端
 */
public class ClientTest {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 8080);

            String aline = new String();
            
            // 獲取輸入流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            aline = bufferedReader.readLine();

            // 訪問(wèn)失敗
            if (!aline.equals("verifying server!")) {
                System.out.println("Server Wrong!");
                return;
            }

            // 獲取響應(yīng)結(jié)果
            String feedback = bufferedReader.readLine();

            while (feedback == null || feedback.equals("PassWord Wrong!")) {
                if (feedback != null) {
                    if (feedback.equals("PassWord Wrong!")) {
                        System.out.println("PassWord Wrong!");
                    } else if (feedback.equals("Registration Successful!")) {
                        System.out.println("Registration Successful!");
                        break;
                    }
                }

                System.out.println("輸入密碼:");
                
                // 輸入密碼
                Scanner scanner = new Scanner(System.in);
                OutputStream outputStream = socket.getOutputStream();
                String password = scanner.nextLine();
                outputStream.write(password.getBytes());
                
                feedback = bufferedReader.readLine();
            }

            // 關(guān)閉連接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

初步實(shí)現(xiàn)后,運(yùn)行:一片空白。什么都沒(méi)有發(fā)生。

出問(wèn)題了很正常,斷點(diǎn)調(diào)試一下吧。發(fā)現(xiàn)問(wèn)題所在:

客戶端執(zhí)行到這一行時(shí),停止,然后服務(wù)器端接著執(zhí)行;

同樣的服務(wù)器端也到這行就停止了。

原因是服務(wù)器一方等著輸入密碼,而客戶端一方等著響應(yīng)結(jié)果,然后又沒(méi)有開(kāi)始輸入密碼。所以雙方就這么一直等著,誰(shuí)都不動(dòng)了。

解決

通過(guò)上面的分析,我們只要將僵局打破就能夠解決問(wèn)題。所以就先輸入密碼,然后再獲取響應(yīng)結(jié)果。這樣就不會(huì)出問(wèn)題了。

所以服務(wù)器端的代碼并不需要做什么改動(dòng),只用修改客戶端程序就行了。

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

/**
 * 客戶端
 */
public class ClientTest {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 8080);

            String aline = new String();
            
            // 獲取輸入流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            aline = bufferedReader.readLine();

            // 訪問(wèn)失敗
            if (!aline.equals("verifying server!")) {
                System.out.println("Server Wrong!");
                return;
            }

            // 主要修改這里,不先獲取響應(yīng)結(jié)果
            // 初始化響應(yīng)結(jié)果
            String feedback = null;

            while (true) {
                if (feedback != null) {
                    if (feedback.equals("PassWord Wrong!")) {
                        System.out.println("PassWord Wrong!");
                    } else if (feedback.equals("Registration Successful!")) {
                        System.out.println("Registration Successful!");
                        break;
                    }
                }

                System.out.println("輸入密碼:");
                
                // 輸入密碼
                Scanner scanner = new Scanner(System.in);
                OutputStream outputStream = socket.getOutputStream();
                String password = scanner.nextLine();
                outputStream.write(password.getBytes());
                
                feedback = bufferedReader.readLine();
            }

            // 關(guān)閉連接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

成功實(shí)現(xiàn)!

升級(jí):利用多線程實(shí)現(xiàn)

功能成功實(shí)現(xiàn)之后,還不能滿足于當(dāng)前的狀況。由于在實(shí)際使用socket的時(shí)候,很多時(shí)候都不是簡(jiǎn)單的一對(duì)一的情況,這種情況下,就需要使用多線程來(lái)幫助我們了。

使用多線程,我們可以實(shí)現(xiàn)一個(gè)服務(wù)器多個(gè)客戶端的情況,每當(dāng)有一個(gè)客戶端請(qǐng)求連接,我們就會(huì)建立一個(gè)線程。

1.服務(wù)器端線程實(shí)現(xiàn)

首先將服務(wù)器獨(dú)立成一個(gè)線程:

/**
 * 服務(wù)器線程
 */
public class ServerThread extends Thread {
    private ServerSocket serverSocket;
    private Socket clientSocket;

    public ServerThread(int port) {
        try {
            serverSocket = new ServerSocket(port);
            // 接受客戶端連接請(qǐng)求
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在構(gòu)造函數(shù)中我們初始化服務(wù)器的socket,然后等待客戶端的連接。接著就是最主要的部分了,線程主要執(zhí)行的邏輯功能:run

@Override
public void run() {
    try {
        // 提示連接成功
        DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
        dataOutputStream.writeUTF("verifying server!");

        // 獲取輸入流
        InputStream inputStream = clientSocket.getInputStream();
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        String password = dataInputStream.readUTF();

        // 獲取登錄信息,允許3次登錄
        int time = 0;

        // 密碼校驗(yàn),允許輸入3次
        while (time < 3) {
            if (password.equals("123")) {
                dataOutputStream.writeUTF("Registration Successful!");
                break;
            } else {
                dataOutputStream.writeUTF("PassWord Wrong!");
                password = dataInputStream.readUTF();
                time++;
            }
        }

        if (time >= 3) {
            dataOutputStream.writeUTF("Illegal User!");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

run沒(méi)有什么可以說(shuō)的,主要就是實(shí)現(xiàn)服務(wù)器與客戶端交互的時(shí)候執(zhí)行的功能。然后在執(zhí)行線程的時(shí)候,會(huì)自動(dòng)調(diào)用run方法。

最后就是啟動(dòng)服務(wù)器端了:

/**
 * 服務(wù)器端
 */
public class ServiceTest {
    public static void main(String[] args) {
        ServerThread serverThread = new ServerThread(8080);
        serverThread.start();
    }
}

同樣,啟用8080端口。

2.客戶端線程實(shí)現(xiàn)

類似服務(wù)器端,首先先建立客戶端線程:

/**
 * 客戶端線程
 */
public class ClientThread extends Thread {
    private Socket socket;

    public ClientThread(String host, int port) {
        try {
            this.socket = new Socket(host, port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在構(gòu)造函數(shù)中,建立客戶端的socket對(duì)象。然后實(shí)現(xiàn)run方法。

@Override
public void run() {
    try {
        // 獲取輸入流
        DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
        String aline = dataInputStream.readUTF();

        // 連接服務(wù)器失敗
        if (!aline.equals("verifying server!")) {
            System.out.println("Server Wrong!");
            return;
        }

        // 獲取響應(yīng)結(jié)果
        String feedback = null;

        // 進(jìn)行密碼輸入
        while (true) {
            if (feedback != null) {
                if (feedback.equals("PassWord Wrong!")) {
                    System.out.println("PassWord Wrong!");
                } else if (feedback.equals("Registration Successful!")) {
                    System.out.println("Registration Successful!");
                    System.exit(1);
                }
            }

            System.out.println("輸入密碼:");
            Scanner scanner = new Scanner(System.in);
            DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
            String password = scanner.nextLine();
            dataOutputStream.writeUTF(password);
            
            // 獲取響應(yīng)結(jié)果
            feedback = dataInputStream.readUTF();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

run方法中,主要實(shí)現(xiàn)了輸入密碼的功能。

最后就是啟動(dòng)客戶端線程:

 /**
 * 客戶端
 */
public class ClientTest {
    public static void main(String[] args) {
        ClientThread clientThread = new ClientThread("127.0.0.1", 8080);
        clientThread.start();
    }
}
總結(jié)

這次的實(shí)驗(yàn)給我提了個(gè)醒,看似簡(jiǎn)單的東西,也永遠(yuǎn)不要輕視它。只有拿出應(yīng)有的實(shí)例去解決問(wèn)題,問(wèn)題才是你眼中那個(gè)簡(jiǎn)單的問(wèn)題。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/71987.html

相關(guān)文章

  • Java015-網(wǎng)絡(luò)編程

    摘要:具備發(fā)送和接受功能,在進(jìn)行傳輸時(shí),需要明確一個(gè)是發(fā)送端,一個(gè)是接收端。指定發(fā)送端口,不指定系統(tǒng)會(huì)隨機(jī)分配。傳輸兩個(gè)端點(diǎn)的建立連接后會(huì)有一個(gè)傳輸數(shù)據(jù)的通道,這通道稱為流,而且是建立在網(wǎng)絡(luò)基礎(chǔ)上的流,稱之為流。 端口:物理端口:邏輯端口: 用于標(biāo)識(shí)進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識(shí);有效端口:0~65535,其中0~1024系統(tǒng)使用或保留端口。 java 中ip對(duì)象:InetAddress....

    Blackjun 評(píng)論0 收藏0
  • 初探Java Socket

    摘要:綁定完成后允許套接字進(jìn)行連接并等待連接。服務(wù)端根據(jù)報(bào)文返回響應(yīng),并關(guān)閉連接。單線程服務(wù)器多進(jìn)程及多線程服務(wù)器復(fù)用服務(wù)器復(fù)用的多線程服務(wù)器單線程服務(wù)器一次只處理一個(gè)請(qǐng)求,直到其完成為止。 前言 本篇文章將涉及以下內(nèi)容: IO實(shí)現(xiàn)Java Socket通信 NIO實(shí)現(xiàn)Java Socket通信 閱讀本文之前最好了解過(guò): Java IO Java NIO Java Concurrenc...

    張漢慶 評(píng)論0 收藏0
  • Java Socke 探究

    摘要:在設(shè)定時(shí)間內(nèi)接收到相應(yīng)操作的請(qǐng)求則返回可以處理請(qǐng)求的數(shù)量,否則在超時(shí)后返回,程序繼續(xù)執(zhí)行。使用接收請(qǐng)求并處理接收到請(qǐng)求后調(diào)用返回的集合。保存了處理當(dāng)前請(qǐng)求的和,并提供了不同的操作類型。默認(rèn)值為且其值必須小于的值。 Java中的Socket可以分為普通Socket和NioSocket兩種。 普通Socket的用法 Java中的網(wǎng)絡(luò)通信是通過(guò)Socket實(shí)現(xiàn)的,Socket分為Server...

    Imfan 評(píng)論0 收藏0
  • JAVA NIO 一步步構(gòu)建I/O多路復(fù)用的請(qǐng)求模型

    摘要:為解決這問(wèn)題,我們發(fā)現(xiàn)元兇處在一線程一請(qǐng)求上,如果一個(gè)線程能同時(shí)處理多個(gè)請(qǐng)求,那么在高并發(fā)下性能上會(huì)大大改善。這樣一個(gè)線程可以同時(shí)發(fā)起多個(gè)調(diào)用,并且不需要同步等待數(shù)據(jù)就緒。表示當(dāng)前就緒的事件類型。 JAVA NIO 一步步構(gòu)建I/O多路復(fù)用的請(qǐng)求模型 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog 文章一:JAVA ...

    X_AirDu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<