Java中的網(wǎng)絡(luò)編程

Transmission Control Protocol/Internet Protocol的簡寫,中譯名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又名網(wǎng)絡(luò)通訊協(xié)議,是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),由網(wǎng)絡(luò)層的IP協(xié)議和傳輸層的TCP協(xié)議組成。TCP/IP 定義了電子設(shè)備如何連入因特網(wǎng),以及數(shù)據(jù)如何在它們之間傳輸?shù)臉?biāo)準(zhǔn)。協(xié)議采用了4層的層級結(jié)構(gòu),每一層都呼叫它的下一層所提供的協(xié)議來完成自己的需求。通俗而言:TCP負(fù)責(zé)發(fā)現(xiàn)傳輸?shù)膯栴},一有問題就發(fā)出信號,要求重新傳輸,直到所有數(shù)據(jù)安全正確地傳輸?shù)侥康牡?。而IP是給因特網(wǎng)的每一臺聯(lián)網(wǎng)設(shè)備規(guī)定一個地址。

通俗的說TCP/IP就是一些列的網(wǎng)絡(luò)通訊規(guī)則。

在TCP/IP參考模型中,將網(wǎng)絡(luò)分為以下幾層:

應(yīng)用層
傳輸層
網(wǎng)際層
主機至網(wǎng)絡(luò)層

而java中的網(wǎng)絡(luò)編程一般是在傳輸層,而其他情況下都是在應(yīng)用層進行開發(fā)(如java web/android的App開發(fā)等等)

網(wǎng)絡(luò)通訊要素

IP地址:InetAddress

-網(wǎng)絡(luò)中設(shè)備的標(biāo)識
-不易記憶,可用主機名
-本地回環(huán)地址:127.0.0.1 主機名:localhost

端口號

-用于標(biāo)識進程的邏輯地址,不同進程的標(biāo)識
-有效端口:0~65535,其中0~1024系統(tǒng)使用或保留端口。

傳輸協(xié)議

-通訊的規(guī)則
-常見協(xié)議:TCP,UDP

class IPDemo {
    public static void main(String[] args) throws Exception {
        // 返回本機主機名
        // InetAddress i = InetAddress.getLocalHost();

        // System.out.println(i.toString());
        // System.out.println("address:"+i.getHostAddress());
        // System.out.println("name:"+i.getHostName());

        InetAddress ia = InetAddress.getByName("thinkpad-sl400");
        System.out.println("address:" + ia.getHostAddress());
        System.out.println("name:" + ia.getHostName());

    }
}

UDP與TCP

UDP的特點

- 將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接

- 每個數(shù)據(jù)報的大小在限制在64k內(nèi)

- 因無連接,是不可靠協(xié)議

- 不需要建立連接,速度快

面向無連接,不管對方在不在都會發(fā)送數(shù)據(jù),而且數(shù)據(jù)容易丟失

TCP的特點:

建立連接,形成傳輸數(shù)據(jù)的通道。

在連接中進行大數(shù)據(jù)量傳輸

通過三次握手完成連接,是可靠協(xié)議

必須建立連接,效率會稍低

Socket

Socket就是為網(wǎng)絡(luò)服務(wù)提供的一種機制。

通信的兩端都有Socket。

網(wǎng)絡(luò)通信其實就是Socket間的通信。

數(shù)據(jù)在兩個Socket間通過IO傳輸。

UDP傳輸?shù)氖褂茫?/h3>
1、DatagramSocket與DatagramPacket

2、建立發(fā)送端,接收端。

3、建立數(shù)據(jù)包。

4、調(diào)用Socket的發(fā)送接收方法。

5、關(guān)閉Socket。
發(fā)送端與接收端是兩個獨立的運行程序

UDP的使用Demo1:

需求:通過udp傳輸方式,將一段文字?jǐn)?shù)據(jù)發(fā)送出去。,
定義一個udp發(fā)送端。
思路:
1,建立updsocket服務(wù)。
2,提供數(shù)據(jù),并將數(shù)據(jù)封裝到數(shù)據(jù)包中。
3,通過socket服務(wù)的發(fā)送功能,將數(shù)據(jù)包發(fā)出去。
4,關(guān)閉資源。

代碼如下:

class UdpSend {
    public static void main(String[] args) throws Exception {
        // 1,創(chuàng)建udp服務(wù)。通過DatagramSocket對象。
        DatagramSocket ds = new DatagramSocket(8888);

        // 2,確定數(shù)據(jù),并封裝成數(shù)據(jù)包。DatagramPacket(byte[] buf, int length, InetAddress
        // address, int port)

        byte[] buf = "udp ge men lai le ".getBytes();
        DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.254"), 10000);

        // 3,通過socket服務(wù),將已有的數(shù)據(jù)包發(fā)送出去。通過send方法。
        ds.send(dp);

        // 4,關(guān)閉資源。

        ds.close();

    }
}

/*
 * 需求: 定義一個應(yīng)用程序,用于接收udp協(xié)議傳輸?shù)臄?shù)據(jù)并處理的。
 * 定義udp的接收端。 思路: 1,定義udpsocket服務(wù)。通常會監(jiān)聽一個端口。其實就是給這個接收網(wǎng)絡(luò)應(yīng)用程序定義數(shù)字標(biāo)識。
 * 方便于明確哪些數(shù)據(jù)過來該應(yīng)用程序可以處理。
 * 2,定義一個數(shù)據(jù)包,因為要存儲接收到的字節(jié)數(shù)據(jù)。 因為數(shù)據(jù)包對象中有更多功能可以提取字節(jié)數(shù)據(jù)中的不同數(shù)據(jù)信息。
 * 3,通過socket服務(wù)的receive方法將收到的數(shù)據(jù)存入已定義好的數(shù)據(jù)包中。 4,通過數(shù)據(jù)包對象的特有功能。將這些不同的數(shù)據(jù)取出。打印在控制臺上。
 * 5,關(guān)閉資源。
 */

class UdpRece {
    public static void main(String[] args) throws Exception {
        // 1,創(chuàng)建udp socket,建立端點。
        DatagramSocket ds = new DatagramSocket(10000);
        while (true) {
            // 2,定義數(shù)據(jù)包。用于存儲數(shù)據(jù)。
            byte[] buf = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);

            // 3,通過服務(wù)的receive方法將收到數(shù)據(jù)存入數(shù)據(jù)包中。
            ds.receive(dp);// 阻塞式方法。

            // 4,通過數(shù)據(jù)包的方法獲取其中的數(shù)據(jù)。
            String ip = dp.getAddress().getHostAddress();

            String data = new String(dp.getData(), 0, dp.getLength());

            int port = dp.getPort();

            System.out.println(ip + "::" + data + "::" + port);

        }
        // 5,關(guān)閉資源
        // ds.close();

    }
}

建議的UDP聊天工具:

/*
 * 編寫一個聊天程序。 有收數(shù)據(jù)的部分,和發(fā)數(shù)據(jù)的部分。 這兩部分需要同時執(zhí)行。 那就需要用到多線程技術(shù)。 一個線程控制收,一個線程控制發(fā)。
 * 因為收和發(fā)動作是不一致的,所以要定義兩個run方法。 而且這兩個方法要封裝到不同的類中。
 */
import java.io.*;
import java.net.*;

class Send implements Runnable {
    private DatagramSocket ds;

    public Send(DatagramSocket ds) {
        this.ds = ds;
    }

    public void run() {
        try {
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

            String line = null;

            while ((line = bufr.readLine()) != null) {

                byte[] buf = line.getBytes();

                DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 10002);

                ds.send(dp);

                if ("886".equals(line))
                    break;
            }
        } catch (Exception e) {
            throw new RuntimeException("發(fā)送端失敗");
        }
    }
}

class Rece implements Runnable {

    private DatagramSocket ds;

    public Rece(DatagramSocket ds) {
        this.ds = ds;
    }

    public void run() {
        try {
            while (true) {
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf, buf.length);

                ds.receive(dp);

                String ip = dp.getAddress().getHostAddress();

                String data = new String(dp.getData(), 0, dp.getLength());

                if ("886".equals(data)) {
                    System.out.println(ip + "....離開聊天室");
                    break;
                }

                System.out.println(ip + ":" + data);
            }
        } catch (Exception e) {
            throw new RuntimeException("接收端失敗");
        }
    }
}

class ChatDemo {
    public static void main(String[] args) throws Exception {
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10002);

        new Thread(new Send(sendSocket)).start();
        new Thread(new Rece(receSocket)).start();

    }
}

TCP的使用

1、Socket和ServerSocket

2、建立客戶端和服務(wù)器端

3、建立連接后,通過Socket中的IO流進行數(shù)據(jù)的傳輸

4、關(guān)閉socket

同樣,客戶端與服務(wù)器端是兩個獨立的應(yīng)用程序。

TCP鏈接可以用三次握手兩次揮手來形容。

TCP使用Demo1:

/*
 * 演示tcp傳輸。
 * 1,tcp分客戶端和服務(wù)端。 2,客戶端對應(yīng)的對象是Socket。 服務(wù)端對應(yīng)的對象是ServerSocket。
 */

/*
 * 客戶端, 通過查閱socket對象,發(fā)現(xiàn)在該對象建立時,就可以去連接指定主機。 因為tcp是面向連接的。所以在建立socket服務(wù)時,
 * 就要有服務(wù)端存在,并連接成功。形成通路后,在該通道進行數(shù)據(jù)的傳輸。
 * 需求:給服務(wù)端發(fā)送給一個文本數(shù)據(jù)。
 * 步驟: 1,創(chuàng)建Socket服務(wù)。并指定要連接的主機和端口。
 * 
 */
import java.io.*;
import java.net.*;

class TcpClient {
    public static void main(String[] args) throws Exception {
        // 創(chuàng)建客戶端的socket服務(wù)。指定目的主機和端口
        Socket s = new Socket("192.168.1.254", 10003);

        // 為了發(fā)送數(shù)據(jù),應(yīng)該獲取socket流中的輸出流。
        OutputStream out = s.getOutputStream();

        out.write("tcp ge men lai le ".getBytes());

        s.close();
    }
}

/*
 * 需求:定義端點接收數(shù)據(jù)并打印在控制臺上。
 * 服務(wù)端: 1,建立服務(wù)端的socket服務(wù)。ServerSocket(); 并監(jiān)聽一個端口。 2,獲取連接過來的客戶端對象。
 * 通過ServerSokcet的 accept方法。沒有連接就會等,所以這個方法阻塞式的。
 * 3,客戶端如果發(fā)過來數(shù)據(jù),那么服務(wù)端要使用對應(yīng)的客戶端對象,并獲取到該客戶端對象的讀取流來讀取發(fā)過來的數(shù)據(jù)。 并打印在控制臺。
 * 4,關(guān)閉服務(wù)端。(可選)
 */
class TcpServer {
    public static void main(String[] args) throws Exception {
        // 建立服務(wù)端socket服務(wù)。并監(jiān)聽一個端口。
        ServerSocket ss = new ServerSocket(10003);

        // 通過accept方法獲取連接過來的客戶端對象。
        while (true) {
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            System.out.println(ip + ".....connected");

            // 獲取客戶端發(fā)送過來的數(shù)據(jù),那么要使用客戶端對象的讀取流來讀取數(shù)據(jù)。
            InputStream in = s.getInputStream();

            byte[] buf = new byte[1024];
            int len = in.read(buf);

            System.out.println(new String(buf, 0, len));

            s.close();// 關(guān)閉客戶端.
        }
        // ss.close();
    }
}

TCP使用demo2:

import java.io.*;
import java.net.*;
/*
 * 演示tcp的傳輸?shù)目蛻舳撕头?wù)端的互訪。
 * 需求:客戶端給服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端收到后,給客戶端反饋信息。
 */

/*
 * 客戶端: 1,建立socket服務(wù)。指定要連接主機和端口。 2,獲取socket流中的輸出流。將數(shù)據(jù)寫到該流中。通過網(wǎng)絡(luò)發(fā)送給服務(wù)端。
 * 3,獲取socket流中的輸入流,將服務(wù)端反饋的數(shù)據(jù)獲取到,并打印。 4,關(guān)閉客戶端資源。
 * 
 */
class TcpClient2 {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("192.168.1.254", 10004);

        OutputStream out = s.getOutputStream();

        out.write("服務(wù)端,你好".getBytes());

        InputStream in = s.getInputStream();

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        System.out.println(new String(buf, 0, len));

        s.close();
    }
}

class TcpServer2 {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10004);

        Socket s = ss.accept();

        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + "....connected");
        InputStream in = s.getInputStream();

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        System.out.println(new String(buf, 0, len));

        OutputStream out = s.getOutputStream();

        Thread.sleep(10000);
        out.write("哥們收到,你也好".getBytes());

        s.close();

        ss.close();
    }
}

TCP使用Demo3:

/*
 * 需求:建立一個文本轉(zhuǎn)換服務(wù)器。 客戶端給服務(wù)端發(fā)送文本,服務(wù)單會將文本轉(zhuǎn)成大寫在返回給客戶端。
 * 而且客戶度可以不斷的進行文本轉(zhuǎn)換。當(dāng)客戶端輸入over時,轉(zhuǎn)換結(jié)束。
 * 分析: 客戶端: 既然是操作設(shè)備上的數(shù)據(jù),那么就可以使用io技術(shù),并按照io的操作規(guī)律來思考。 源:鍵盤錄入。 目的:網(wǎng)絡(luò)設(shè)備,網(wǎng)絡(luò)輸出流。
 * 而且操作的是文本數(shù)據(jù)??梢赃x擇字符流。
 * 步驟 1,建立服務(wù)。 2,獲取鍵盤錄入。 3,將數(shù)據(jù)發(fā)給服務(wù)端。 4,后去服務(wù)端返回的大寫數(shù)據(jù)。 5,結(jié)束,關(guān)資源。
 * 都是文本數(shù)據(jù),可以使用字符流進行操作,同時提高效率,加入緩沖。
 */
import java.io.*;
import java.net.*;

class TransClient {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("192.168.1.254", 10005);

        // 定義讀取鍵盤數(shù)據(jù)的流對象。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        // 定義目的,將數(shù)據(jù)寫入到socket輸出流。發(fā)給服務(wù)端。
        // BufferedWriter bufOut =
        // new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        PrintWriter out = new PrintWriter(s.getOutputStream(), true);

        // 定義一個socket讀取流,讀取服務(wù)端返回的大寫信息。
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String line = null;

        while ((line = bufr.readLine()) != null) {
            if ("over".equals(line))
                break;

            out.println(line);
            // bufOut.write(line);
            // bufOut.newLine();
            // bufOut.flush();

            String str = bufIn.readLine();
            System.out.println("server:" + str);

        }

        bufr.close();
        s.close();

    }
}

/*
 * 服務(wù)端: 源:socket讀取流。 目的:socket輸出流。 都是文本,裝飾。
 */
class TransServer {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10005);

        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + "....connected");

        // 讀取socket讀取流中的數(shù)據(jù)。
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        // 目的。socket輸出流。將大寫數(shù)據(jù)寫入到socket輸出流,并發(fā)送給客戶端。
        // BufferedWriter bufOut =
        // new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        PrintWriter out = new PrintWriter(s.getOutputStream(), true);

        String line = null;
        while ((line = bufIn.readLine()) != null) {

            System.out.println(line);

            out.println(line.toUpperCase());
            // bufOut.write(line.toUpperCase());
            // bufOut.newLine();
            // bufOut.flush();
        }

        s.close();
        ss.close();

    }
}

TCP使用Demo4,上傳文本:

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

class TextClient {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("192.168.1.254", 10006);

        BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java"));

        PrintWriter out = new PrintWriter(s.getOutputStream(), true);

        String line = null;
        while ((line = bufr.readLine()) != null) {
            out.println(line);
        }

        s.shutdownOutput();// 關(guān)閉客戶端的輸出流。相當(dāng)于給流中加入一個結(jié)束標(biāo)記-1.

        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String str = bufIn.readLine();
        System.out.println(str);

        bufr.close();

        s.close();
    }
}

class TextServer {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10006);

        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + "....connected");

        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        PrintWriter out = new PrintWriter(new FileWriter("server.txt"), true);

        String line = null;

        while ((line = bufIn.readLine()) != null) {
            // if("over".equals(line))
            // break;
            out.println(line);
        }

        PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
        pw.println("上傳成功");

        out.close();
        s.close();
        ss.close();

    }
}

TCP使用之上傳圖片

/*
 * 需求:上傳圖片。
 */

/*
 * 客戶端。 
 * 1,服務(wù)端點。 
 * 2,讀取客戶端已有的圖片數(shù)據(jù)。 
 * 3,通過socket 輸出流將數(shù)據(jù)發(fā)給服務(wù)端。 
 * 4,讀取服務(wù)端反饋信息。 
 * 5,關(guān)閉。
 */

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

class PicClient {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("192.168.1.254", 10007);

        FileInputStream fis = new FileInputStream("c:\\1.bmp");

        OutputStream out = s.getOutputStream();

        byte[] buf = new byte[1024];

        int len = 0;

        while ((len = fis.read(buf)) != -1) {
            out.write(buf, 0, len);
        }

        // 告訴服務(wù)端數(shù)據(jù)已寫完
        s.shutdownOutput();

        InputStream in = s.getInputStream();

        byte[] bufIn = new byte[1024];

        int num = in.read(bufIn);
        System.out.println(new String(bufIn, 0, num));

        fis.close();
        s.close();
    }
}

/*
 * 服務(wù)端
 */
class PicServer {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10007);

        Socket s = ss.accept();

        InputStream in = s.getInputStream();

        FileOutputStream fos = new FileOutputStream("server.bmp");

        byte[] buf = new byte[1024];

        int len = 0;
        while ((len = in.read(buf)) != -1) {
            fos.write(buf, 0, len);
        }

        OutputStream out = s.getOutputStream();

        out.write("上傳成功".getBytes());

        fos.close();

        s.close();

        ss.close();
    }
}

TCP之多線程上傳圖片

/*
 * 需求:上傳圖片。
 */
/*
 * 客戶端。
 *  1,服務(wù)端點。
 *  2,讀取客戶端已有的圖片數(shù)據(jù)。 
 *  3,通過socket 輸出流將數(shù)據(jù)發(fā)給服務(wù)端。
 *  4,讀取服務(wù)端反饋信息。 
 *  5,關(guān)閉。
 * 
 */

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

class PicClient {
    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.out.println("請選擇一個jpg格式的圖片");
            return;
        }

        File file = new File(args[0]);
        if (!(file.exists() && file.isFile())) {
            System.out.println("該文件有問題,要么補存在,要么不是文件");
            return;

        }

        if (!file.getName().endsWith(".jpg")) {
            System.out.println("圖片格式錯誤,請重新選擇");
            return;
        }

        if (file.length() > 1024 * 1024 * 5) {
            System.out.println("文件過大,沒安好心");
            return;
        }

        Socket s = new Socket("192.168.1.254", 10007);

        FileInputStream fis = new FileInputStream(file);

        OutputStream out = s.getOutputStream();

        byte[] buf = new byte[1024];

        int len = 0;

        while ((len = fis.read(buf)) != -1) {
            out.write(buf, 0, len);
        }

        // 告訴服務(wù)端數(shù)據(jù)已寫完
        s.shutdownOutput();

        InputStream in = s.getInputStream();

        byte[] bufIn = new byte[1024];

        int num = in.read(bufIn);
        System.out.println(new String(bufIn, 0, num));

        fis.close();
        s.close();
    }
}

/*
 * 服務(wù)端
 * 
 * 這個服務(wù)端有個局限性。當(dāng)A客戶端連接上以后。被服務(wù)端獲取到。服務(wù)端執(zhí)行具體流程。 這時B客戶端連接,只有等待。
 * 因為服務(wù)端還沒有處理完A客戶端的請求,還有循環(huán)回來執(zhí)行下次accept方法。所以 暫時獲取不到B客戶端對象。
 * 那么為了可以讓多個客戶端同時并發(fā)訪問服務(wù)端。 那么服務(wù)端最好就是將每個客戶端封裝到一個單獨的線程中,這樣,就可以同時處理多個客戶端請求。
 * 如何定義線程呢?
 * 
 * 只要明確了每一個客戶端要在服務(wù)端執(zhí)行的代碼即可。將該代碼存入run方法中。
 */

class PicThread implements Runnable {

    private Socket s;

    PicThread(Socket s) {
        this.s = s;
    }

    public void run() {

        int count = 1;
        String ip = s.getInetAddress().getHostAddress();
        try {
            System.out.println(ip + "....connected");

            InputStream in = s.getInputStream();

            File dir = new File("d:\\pic");

            File file = new File(dir, ip + "(" + (count) + ")" + ".jpg");

            while (file.exists())
                file = new File(dir, ip + "(" + (count++) + ")" + ".jpg");

            FileOutputStream fos = new FileOutputStream(file);

            byte[] buf = new byte[1024];

            int len = 0;
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

            OutputStream out = s.getOutputStream();

            out.write("上傳成功".getBytes());

            fos.close();

            s.close();
        } catch (Exception e) {
            throw new RuntimeException(ip + "上傳失敗");
        }
    }
}

class PicServer {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10007);

        while (true) {
            Socket s = ss.accept();

            new Thread(new PicThread(s)).start();
        }

        // ss.close();
    }
}

TCP使用之并發(fā)登陸

/*
 * 客戶端通過鍵盤錄入用戶名。 服務(wù)端對這個用戶名進行校驗。
 * 如果該用戶存在,在服務(wù)端顯示xxx,已登陸。 并在客戶端顯示 xxx,歡迎光臨。
 * 如果該用戶存在,在服務(wù)端顯示xxx,嘗試登陸。 并在客戶端顯示 xxx,該用戶不存在。
 * 最多就登錄三次。
 */
import java.io.*;
import java.net.*;

class LoginClient {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("192.168.1.254", 10008);

        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        PrintWriter out = new PrintWriter(s.getOutputStream(), true);

        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        for (int x = 0; x < 3; x++) {
            String line = bufr.readLine();
            if (line == null)
                break;
            out.println(line);

            String info = bufIn.readLine();
            System.out.println("info:" + info);
            if (info.contains("歡迎"))
                break;

        }

        bufr.close();
        s.close();
    }
}

class UserThread implements Runnable {
    private Socket s;

    UserThread(Socket s) {
        this.s = s;
    }

    public void run() {
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + "....connected");
        try {
            for (int x = 0; x < 3; x++) {
                BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

                String name = bufIn.readLine();
                if (name == null)
                    break;

                BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));

                PrintWriter out = new PrintWriter(s.getOutputStream(), true);

                String line = null;

                boolean flag = false;
                while ((line = bufr.readLine()) != null) {
                    if (line.equals(name)) {
                        flag = true;
                        break;
                    }
                }

                if (flag) {
                    System.out.println(name + ",已登錄");
                    out.println(name + ",歡迎光臨");
                    break;
                } else {
                    System.out.println(name + ",嘗試登錄");
                    out.println(name + ",用戶名不存在");
                }

            }
            s.close();
        } catch (Exception e) {
            throw new RuntimeException(ip + "校驗失敗");
        }
    }
}

class LoginServer {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(10008);

        while (true) {
            Socket s = ss.accept();

            new Thread(new UserThread(s)).start();
        }
    }
}    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java中的網(wǎng)絡(luò)編程 Transmission Control Protocol/Internet Protoco...
    寶塔山上的貓閱讀 290評論 0 0
  • 網(wǎng)絡(luò)概念第一天 兩臺電腦怎么通過網(wǎng)絡(luò)傳輸數(shù)據(jù)?怎樣才能知道傳輸?shù)氖菙?shù)據(jù)?誰摸過網(wǎng)線? 看電影,怎么看的?通過電流,...
    小吖朱閱讀 1,647評論 0 1
  • 1. 網(wǎng)絡(luò)編程概述 1.1 計算機網(wǎng)絡(luò) 是指將地理位置不同的具有獨立功能的多臺計算機及其外部設(shè)備,通過通信線路連接...
    JackChen1024閱讀 1,129評論 0 3
  • 01 我記得 那是花紅柳綠的季節(jié) 在校園的農(nóng)場里 我們盡情奔跑 放飛夢想 手里的魚線一圈圈減少 空中的風(fēng)箏越飛越高...
    王木木勿忘初心閱讀 246評論 0 1
  • 在夜涼如水的萍水畔 我和愛的人在這里相會 我的心里的激動逃避不了 她溫柔的言語令我心醉 她說今晚的夜色多么美好 我...
    過路的蜻蜓閱讀 249評論 0 3

友情鏈接更多精彩內(nèi)容