第84節:Java中的網絡編程(中)

標題圖

第84節:Java中的網絡編程(中)java

實現客戶端和服務端的通訊:編程

客戶端須要的操做,建立socket,明確地址和端口,進行鍵盤錄入,獲取須要的數據,而後將錄入的數據發送給服務端,爲socket輸出流,而後進行讀取服務端發送回來的大寫數據,爲socket讀取流,最後進行客戶端顯示器的顯示,進行讀寫操做,關閉資源。瀏覽器

網絡編程TCP客戶端服務器

package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TransClient {

    public static void main(String[] args) throws IOException {
        // 客戶端
        // 建立socket 明確地址和端口
        Socket s = new Socket("192.168.1.151",10005);
        
        // 鍵盤錄入
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        
        // 網絡, socket輸出流
//      OutputStream out = s.getOutputStream();
        
        // 傳的是字符數據, 轉換,提升效率
//      BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out));
        
        // 打印流,既能接收字符又能接收字節
        PrintWriter out = new PrintWriter(s.getOutputStream());
        
        // 讀取流,讀取服務端發來的數據
//      InputStream in = s.getInputStream();
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        // 顯示數據,使用輸出語句
        
        // 頻繁讀寫,讀鍵盤
        String line = null;
        while((line=bufr.readLine()) != null) {
            if("over".equals(line)) {
                break;
            }
            // 讀取鍵盤的數據發送到服務端
            out.println(line);
            
            // 讀取服務端返回的數據
            String upperText = bufIn.readLine();
            System.out.println(upperText);
            
        }
        
        // 關閉資源
        s.close();
        
    }

}

對於服務端,要建立一個服務端的socket,而後明確端口,要讀取客戶端發送過來的數據,要讀取socket輸入流,接着使用socket輸出流,將數據發送給客戶端,進行讀寫操做,關閉資源。網絡

網絡編程TCP服務端架構

package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TransServer {

    public static void main(String[] args) throws IOException {

        System.out.println("服務端運行。。。");
        // 服務端:
        // 建立服務端的socket,明確端口
        ServerSocket ss = new ServerSocket(10005);

        while (true) {
            // 獲取客戶端對象

            Socket s = ss.accept();
            
            // 打印ip地址
            System.out.println(s.getInetAddress().getHostAddress()+"...connected");

            // socket輸入流,讀取客戶端發過來的數據
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

            // socket輸出流,將數據發送給客戶端
//          PrintWriter out = new PrintWriter(s.getOutputStream());
            PrintWriter out = new PrintWriter(s.getOutputStream(), true);

            // 頻繁的讀寫操做
            String line = null;
            while ((line = bufIn.readLine()) != null) {
                // 若是客戶端發送過來的是over
                if ("over".equals(line)) {
                    break;
                }
                
                // 客戶端的數據
                System.out.println(line);
                // 字母轉大寫
                out.println(line.toUpperCase());
                // 都在緩衝區中,刷新
//              out.flush();
            }
            // 關閉客戶端
            s.close();
        }
    }

}
package com.dashucoding.tcp3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TransClient {

    public static void main(String[] args) throws IOException {
        
        System.out.println("客戶端運行。。。");
        // 客戶端
        // 建立socket 明確地址和端口
        Socket s = new Socket("192.168.2.151",10005);
        
        // 鍵盤錄入
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        
        // 網絡, socket輸出流
//      OutputStream out = s.getOutputStream();
        
        // 傳的是字符數據, 轉換,提升效率
//      BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out));
        
        // 打印流,既能接收字符又能接收字節
//      PrintWriter out = new PrintWriter(s.getOutputStream());
        PrintWriter out = new PrintWriter(s.getOutputStream(), true);
        
        // 讀取流,讀取服務端發來的數據
//      InputStream in = s.getInputStream();
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        // 顯示數據,使用輸出語句
        
        // 頻繁讀寫,讀鍵盤
        String line = null;
        // 都一行,有行終止符才返回
        while((line=bufr.readLine()) != null) {
            // 讀取鍵盤的數據發送到服務端
//          out.print(line+"\r\n");
            out.println(line);
            // 刷數據,都在緩衝區中
//          out.flush();
            if("over".equals(line)) {
                break;
            }
            
            // 讀取服務端返回的數據
            String upperText = bufIn.readLine();
            System.out.println(upperText);
            
        }
        
        // 關閉資源
        s.close();
        
    }

}

上傳文件併發

void shutdownInput() 此套接字的輸入流置於「流的末尾」
void shutdownOutput() 禁用此套接字的輸出流
String toString() 將此套接字轉換爲String.

客戶端:app

package com.dashucoding.net.uploadtext;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadTextClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        System.out.println("上傳文件客戶端運行。。。");
        // 客戶端
        // 建立socket 明確地址和端口
        Socket s = new Socket("192.168.43.126", 10006);

        // 讀取文本文件
        BufferedReader bufr = new BufferedReader(new FileReader("tempfile\\client.txt"));
        // 將數據發送給服務端
        PrintWriter out = new PrintWriter(s.getOutputStream(), true);
        
        
        // 顯示數據,使用輸出語句

        // 頻繁讀寫,讀鍵盤
        String line = null;
        // 都一行,有行終止符才返回true
        while ((line = bufr.readLine()) != null) {
            
            out.println(line);

        }
        
        // 給服務端發送一個結束標記,條約標記
//      out.println("over");
        s.shutdownOutput();
        // 向服務端發送告終束標記
        
        // 讀取流,讀取服務端發來的數據
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String info = bufIn.readLine();
        System.out.println(info);
        // 關閉資源
        bufr.close();
        s.close();
    }

}

服務端:socket

package com.dashucoding.net.uploadtext;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadTextServer {

    public static void main(String[] args) throws IOException {
        System.out.println("上傳文本服務端運行。。。");
        // 服務端:
        // 建立服務端的socket,明確端口
        ServerSocket ss = new ServerSocket(10006);

        while (true) {
            // 獲取客戶端對象

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

            // socket輸入流,讀取客戶端發過來的數據
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));

            // socket輸出流,目的是文件
            PrintWriter pw = new PrintWriter(new FileWriter("tempfile\\server.txt"), true);

            // 頻繁的讀寫操做
            String line = null;
            while ((line = bufIn.readLine()) != null) {
                if("over".equals(line)) {
                    break;
                }
                
                pw.println(line);
            }
            
            // 發回給客戶端,上傳成功
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            out.println("上傳成功");
            
            // 關閉客戶端
            s.close();
        }
    }

}

上傳圖片tcp

客戶端:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

    public static void main(String[] args) throws IOException {
        
        System.out.println("上傳圖片客戶端運行。。。");
        // 上傳圖片
        // 建立socket
        Socket s = new Socket("192.168.43.126",10007);
        
        // 讀取圖片,圖片路徑
        File picFile = new File("tempfile\\001.jpg");
        FileInputStream fis = new FileInputStream(picFile);
        
        // socket 輸出流
        OutputStream out = s.getOutputStream();
        
        byte[] buf = new byte[1024];
        int len = 0;
        while((len=fis.read(buf)) != -1) {
            out.write(buf,0,len);
        }
        
        // 告訴服務器端圖片數據發送完畢,不要等着讀了。
        s.shutdownOutput();
        
        // 讀取上傳成功
        InputStream in = s.getInputStream();
        byte[] bufIn = new byte[1024];
        int lenIn = in.read(bufIn);
        System.out.println(new String(bufIn, 0, lenIn));
        
        // 關閉
        fis.close();
        s.close();
        
    }

}

服務端:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

    public static void main(String[] args) throws IOException {
        
        
        System.out.println("上傳圖片服務端運行。。。");
        // 建立serversocket
        ServerSocket ss = new ServerSocket(10007);

        while (true) { // 實現上傳多回
            // 獲取客戶端
            Socket s = ss.accept();
            String ip = s.getInetAddress().getHostAddress();
            System.out.println(ip+"...connected");

            // 讀取圖片數據
            InputStream in = s.getInputStream();

            // 寫圖片數據到文件
            File picFile = new File("tempfile\\server.jpg"); // 存儲圖片
            FileOutputStream fos = new FileOutputStream(picFile);

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

            // 給客戶端返回一個回饋信息
            java.io.OutputStream out = s.getOutputStream();
            out.write("上傳成功".getBytes());

            // 關閉資源
            fos.close();
            s.close();
        }
    }

}

如何解決圖片重名的問題:

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

    public static void main(String[] args) throws IOException {
        
        System.out.println("上傳圖片客戶端運行。。。");
        // 上傳圖片
        // 建立socket
        Socket s = new Socket("192.168",10007);
        
        // 讀取圖片,圖片路徑
        File picFile = new File("tempfile\\001.jpg");
        FileInputStream fis = new FileInputStream(picFile);
        
        // socket 輸出流
        OutputStream out = s.getOutputStream();
        
        byte[] buf = new byte[1024];
        int len = 0;
        while((len=fis.read(buf)) != -1) {
            out.write(buf,0,len);
        }
        
        // 告訴服務器端圖片數據發送完畢,不要等着讀了。
        s.shutdownOutput();
        
        // 讀取上傳成功
        InputStream in = s.getInputStream();
        byte[] bufIn = new byte[1024];
        int lenIn = in.read(bufIn);
        System.out.println(new String(bufIn, 0, lenIn));
        
        // 關閉
        fis.close();
        s.close();
        
    }

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

    public static void main(String[] args) throws IOException {
        
        
        System.out.println("上傳圖片服務端運行。。。");
        // 建立serversocket
        ServerSocket ss = new ServerSocket(10007);

        while (true) { // 實現上傳多回
            // 獲取客戶端
            Socket s = ss.accept();
            String ip = s.getInetAddress().getHostAddress();
            System.out.println(ip+"...connected");

            // 讀取圖片數據
            InputStream in = s.getInputStream();

            // 寫圖片數據到文件
            // 建立目錄
            File dir = new File("e:\\uploadpic");
            // 若是不存在就建立目錄
            if(!dir.exists()) {
                dir.mkdir();
            }
            // 給文件編號
            // 加計數器
            int count = 1;
            // 防止第二次爲0
            File picFile = new File(dir, ip + "("+count+").jpg");
//          if(picFile.exists()) {
            while(picFile.exists()) {
                count++;
                picFile = new File(dir, ip + "("+count+").jpg");
            }
            FileOutputStream fos = new FileOutputStream(picFile);
            
//          File picFile = new File("tempfile\\" + ip + ".jpg");
//          File picFile = new File("tempfile\\server.jpg"); 
            // 存儲圖片
            

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

            // 給客戶端返回一個回饋信息
            java.io.OutputStream out = s.getOutputStream();
            out.write("上傳成功".getBytes());

            // 關閉資源
            fos.close();
            s.close();
        }
    }

}

解決上傳併發的問題

結構

package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

    public static void main(String[] args) throws IOException {
        
        System.out.println("上傳圖片客戶端運行。。。");
        // 上傳圖片
        // 建立socket
        Socket s = new Socket("",10007);
        
        // 讀取圖片,圖片路徑
        File picFile = new File("tempfile\\001.jpg");
        FileInputStream fis = new FileInputStream(picFile);
        
        // socket 輸出流
        OutputStream out = s.getOutputStream();
        
        byte[] buf = new byte[1024];
        int len = 0;
        while((len=fis.read(buf)) != -1) {
            out.write(buf,0,len);
        }
        
        // 告訴服務器端圖片數據發送完畢,不要等着讀了。
        s.shutdownOutput();
        
        // 讀取上傳成功
        InputStream in = s.getInputStream();
        byte[] bufIn = new byte[1024];
        int lenIn = in.read(bufIn);
        System.out.println(new String(bufIn, 0, lenIn));
        
        // 關閉
        fis.close();
        s.close();
        
    }

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class UploadPicServer {

    public static void main(String[] args) throws IOException {

        System.out.println("上傳圖片服務端運行。。。");
        // 建立serversocket
        ServerSocket ss = new ServerSocket(10007);

        while (true) { // 實現上傳多回
            // 獲取客戶端
            Socket s = ss.accept();

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

}
package com.dashucoding.net.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

// 建立任務
// 線程完成任務後,會自動結束
public class UploadPic implements Runnable {

    private Socket s;

    // 建立構造函數
    public UploadPic(Socket s) {
        this.s = s;
    }

    @Override
    public void run() {
        try {
            // 主線程負債接收客戶端,其它線程負責接收數據

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

            // 讀取圖片數據
            InputStream in = s.getInputStream();

            // 寫圖片數據到文件
            // 建立目錄
            File dir = new File("e:\\uploadpic");
            // 若是不存在就建立目錄
            if (!dir.exists()) {
                dir.mkdir();
            }
            // 給文件編號
            // 加計數器
            int count = 1;
            // 防止第二次爲0
            File picFile = new File(dir, ip + "(" + count + ").jpg");
//                      if(picFile.exists()) {
            while (picFile.exists()) {
                count++;
                picFile = new File(dir, ip + "(" + count + ").jpg");
            }
            FileOutputStream fos = new FileOutputStream(picFile);

            // 開始循環進行讀寫操做
            // 一個線程,不能處理併發的數據
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

            // 給客戶端返回一個回饋信息
            java.io.OutputStream out = s.getOutputStream();
            out.write("上傳成功".getBytes());

            // 關閉資源
            fos.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

客戶端:瀏覽器,服務端:Tomcat

端口號,\con\server.xml

效果

瀏覽器發送HTTP請求

GET / HTTP / 1.1
Accept: 
Accept-Language:
Accept-Encoding:
User-Agent:
Host:
Connection:

請求行,協議,應用層協議,超文本傳輸協議,請求方式,訪問資源的路徑,http的協議版本,

效果

package com.dashucoding.net.myserver;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class MyBrowser {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // 瀏覽器發送http消息
        Socket s = new Socket("",8080);
        
        // 把信息發送給服務端
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        out.println("");
        out.println();//空行
        
        // 讀取服務端的數據
        InputStream in = s.getInputStream();
        byte[] buf = new byte[1024];
        String text = new String(buf,0,len);
        System.out.print(text);

        s.close();
    }

}

發送和http協議相同的信息,收到了Tomcat服務器返回的數據。

版本

插件

package com.dashucoding.net.myserver;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class MyBrowserGui extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyBrowserGui frame = new MyBrowserGui();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public MyBrowserGui() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

下載插件

url的描述

java.net
類 url
java.lang.object
java.net.url
全部已實現的接口:
serializable

public final class url extends object implements serializable

url 表示一個統一的資源定位符,用於指向互聯網"資源"的指針。
// 構造方法
url (string spec):
根據string表示形式建立url對象

url (string protocol, string host, int port, string file)
根據指定protocol,host,port號和file建立url對象
package com.dashucoding.net.url;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo {

    public static void main(String[] args) throws IOException {
        
String str_url = "http://";
        
        //將url地址封裝成對象。
        URL url = new URL(str_url);
        
//      System.out.println("getProtocol:"+url.getProtocol());
//      System.out.println("getHost:"+url.getHost());
//      System.out.println("getPort:"+url.getPort());
//      System.out.println("getPath:"+url.getPath());
//      System.out.println("getFile:"+url.getFile());
//      System.out.println("getQuery:"+url.getQuery());
        
        //獲取指定資源的鏈接對象,封裝了socket。
        URLConnection conn = url.openConnection();
        
//      System.out.println(conn);
        
        InputStream in = conn.getInputStream();
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        String text = new String(buf,0,len);
        System.out.println(text);
        
        
    }

}
openConnection
public URLConnection openConnection() throws IOException
返回一個URLConnection對象,它表示到url所引用的遠程對象的鏈接

urlconnection

圖片

package com.dashucoding.net.url;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo {

    public static void main(String[] args) throws IOException {

        String str_url = "http://";

        // 將url地址封裝成對象。
        URL url = new URL(str_url);

//      System.out.println("getProtocol:"+url.getProtocol());
//      System.out.println("getHost:"+url.getHost());
//      System.out.println("getPort:"+url.getPort());
//      System.out.println("getPath:"+url.getPath());
//      System.out.println("getFile:"+url.getFile());
//      System.out.println("getQuery:"+url.getQuery());

        // 獲取指定資源的鏈接對象,封裝了socket。
        URLConnection conn = url.openConnection();

//      System.out.println(conn);

        InputStream in = conn.getInputStream();
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        String text = new String(buf, 0, len);
        System.out.println(text);

    }

}

網絡編程中HTTP版本的區別

http1.0請求一次鏈接就斷開了,一次鏈接只能有一次請求,http1.1一次鏈接屢次請求。

URL用於解析url地址,URLConnection用於獲取url的鏈接。

常見的網絡架構:cs和bs

client / server
客戶端和服務端,維護麻煩

browser / server
只須要服務端,只要系統內置瀏覽器
全部的運算在服務端,簡單易用

結言

好了,歡迎在留言區留言,與你們分享你的經驗和心得。

感謝你學習今天的內容,若是你以爲這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。

達叔小生:日後餘生,惟獨有你
You and me, we are family !
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動而且善於溝通
簡書博客: 達叔小生
https://www.jianshu.com/u/c785ece603d1

結語

  • 下面我將繼續對 其餘知識 深刻講解 ,有興趣能夠繼續關注
  • 小禮物走一走 or 點贊
相關文章
相關標籤/搜索