<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # JAVA之旅(三十三)——TCP傳輸,互相(傷害)傳輸,復制文件,上傳圖片,多并發上傳,多并發登錄 * * * > 我們繼續網絡編程 ## 一.TCP > 說完UDP,我們就來說下我們應該重點掌握的TCP了 * TCP傳輸? * Socket和ServiceSocket * 建立客戶端和服務端 * 建立連接后,通過Socket中的IO流進行數據的傳輸 * 關閉Socket > 同樣的,我們的客戶端和服務端都是兩個獨立的應用 > > 我們通過查閱API文檔發現,該對象在建立的時候,就可以去連接指定主機,因為tcp是面向連接的,所以在建立socket服務時,就要有服務存在,并成功連接,形成通路后,在該通道進行數據傳輸 > > 所以我們用代碼來看下他的步驟 ### 客戶端 ~~~ package com.lgl.hellojava; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class TcpClient { public static void main(String[] args) { try { //1.創建客戶端的服務,傳地址和端口 Socket s = new Socket("192.168.1.102",10000); //2.為了發送數據,應該獲得socket流中的輸出流 OutputStream out = s.getOutputStream(); out.write("你好".getBytes()); s.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ ### 服務端 ~~~ package com.lgl.hellojava; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * 定義端點接收數據打印出來 * 服務端: * 1.建立服務端的socket服務,servicesocket,并監聽一個端口 * 2.獲取連接過來的客戶端對象,通過accept方法,這個方法是阻塞的,沒有連接就會等 * 3.客戶端如果發過來數據,那么服務端要使用對應的客戶端對象,并獲取到該對象的讀取流 * 4.關閉服務端(可選操作) * @author LGL * */ public class TcpService { public static void main(String[] args) { try { //1.建立連接,監聽端口 ServerSocket ss = new ServerSocket(10000); //2.連接客戶端對象 Socket accept = ss.accept(); //獲取ip String ip = accept.getInetAddress().getHostAddress(); //3.獲取客戶端發送過來的數據 InputStream in = accept.getInputStream(); //4.開始讀取 byte [] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); //5.關閉 ss.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ ## 二.TCP互相傳輸 > 我們在來寫一個實例去說明,他們的互訪動作,這里為了寫起來方便,就寫在一個類中了 ~~~ package com.lgl.hellojava; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; /** * 客戶端發送信息,服務端收到,反饋信息 * * @author LGL * */ public class Tcp { public static void main(String[] args) { try { Socket s = new Socket("192.168.1.102", 10005); OutputStream out = s.getOutputStream(); out.write("我是客戶端".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(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 服務端 * @author LGL * */ class Server { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); 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(); out.write("收到后反饋".getBytes()); s.close(); ss.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ ## 三.復制文件 > 同樣的這里也是使用的流,我們具體來看下怎么去操作,我們同樣的,寫在一個類中 ~~~ package com.lgl.socket; import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class FileClient { public static void main(String[] args) { try { Socket s = new Socket("192.168.1.102", 10006); BufferedReader bufr = new BufferedReader(new FileReader("test.txt")); PrintWriter pw = new PrintWriter(s.getOutputStream(), true); String line = null; while ((line = bufr.readLine()) != null) { pw.println(line); } pw.print("over"); BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); String str = bufIn.readLine(); System.out.println(str); bufr.close(); s.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class FileServer { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10006); Socket s = ss.accept(); BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); PrintWriter out = new PrintWriter(new FileWriter("test1.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(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ ## 四.上傳圖片 > 我們再來看下圖片是怎么上傳的,我們先來分析下步驟 ### 客戶端 * 1.服務端點 * 2.讀取客戶端已有的圖片數據 * 3.通過socket,發送給服務端 * 4.讀取服務端反饋的信息 * 5.關閉資源 ~~~ ** * 客戶端 * * @author LGL * */ public class PicClient { public static void main(String[] args) { try { Socket s = new Socket("192.168.1.102", 10009); FileInputStream fis = new FileInputStream("1.png"); OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { out.write(buf, 0, len); } //告訴服務端數據寫完 s.shutdownInput(); InputStream in = s.getInputStream(); byte[] bufn = new byte[1024]; int num = in.read(bufn); System.out.println(new String(bufn, 0, num)); fis.close(); s.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ ### 服務端 > 直接看代碼 ~~~ /** * 服務端 * @author LGL * */ class PicServer { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10009); Socket s = ss.accept(); InputStream in = s.getInputStream(); FileOutputStream fos = new FileOutputStream("2.png"); 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(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ~~~ > 其實跟I/O區別真不大,但是概念一定要了解清楚 ## 五.多并發上傳 > 多并發這個概念就是多人互動了,這對服務器的負荷還是有考究的,這里呢,我們就模擬一下,多人上傳圖片的場景,我們是怎么做的?我們還是在上傳圖片的那份代碼上更改 > > 首先我們可以確定的是,這是服務端的代碼 * 這個服務端有個局限性,當A客戶端連接之后,被服務端獲取到,服務端就在執行代碼了,這個時候如果B客戶端連接只有等待,這就是我們需要多并發的原因了,為了讓多個客戶端同時連接,服務端最好就是講每個客戶端封裝到一個單獨的線程中,這樣就可以同時處理多個客戶端請求 > 如何定義線程? * 只要明確了每個客戶端要在服務端執行的代碼即可 ~~~ /** * 服務端 * * @author LGL * */ class PicServer { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10009); while (true) { Socket s = ss.accept(); new Thread(new PicThread(s)).start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 并發線程 * @author LGL * */ class PicThread implements Runnable { private Socket s; public PicThread(Socket s) { this.s = s; } @Override public void run() { try { String ip = s.getInetAddress().getHostAddress(); System.out.println("ip:" + ip); long millis = System.currentTimeMillis(); File file = new File(millis + ".png"); InputStream in = s.getInputStream(); 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("上傳失敗"); } } } ~~~ > 其實我寫的代碼還是有點爛的,但是思想在就好,我們得先把思想學會了 ## 六.多并發登錄 > 上面說的多并發的上傳,實在服務端端,現在我們來說下登錄,是作用在客戶端 ~~~ package com.lgl.socket; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class LoginClient { public static void main(String[] args) { try { Socket s = new Socket("192.168.1.102", 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 i = 0; i < 3; i++) { 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(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 服務端 * * @author LGL * */ class LoginServer { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(10008); while (true) { Socket s = ss.accept(); new Thread(new UserThread(s)).start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 并發登陸 * * @author LGL * */ class UserThread implements Runnable { private Socket s; public UserThread(Socket s) { this.s = s; } @Override public void run() { for (int i = 0; i < 3; i++) { try { BufferedReader bufrIn = new BufferedReader( new InputStreamReader(s.getInputStream())); String name = bufrIn.readLine(); // 模擬讀取數據庫的用戶名 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("已登錄"); out.print("歡迎"); } else { System.out.println("重新登錄"); out.println("用戶名不存在"); } s.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ~~~ > OK,這些代碼中可能會存在一些錯誤,因為代碼并沒有去實際的驗證中,我寫的時候也是跟著思想去走的,這樣寫代碼是極為友好的,這就是TCP的冰山一角了,不過關于這些,還有很多知識點,我們要做的就是把思想給掌握了,萬變不理其中 > > 好的,最近寫文的時間,有點懈怠了,看來要發力了,嘻嘻, ## 有興趣的加群:555974449 一起來玩玩吧! 版權聲明:本文為博主原創文章,博客地址:http://blog.csdn.net/qq_26787115,未經博主允許不得轉載。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看