黑馬程式員_Java基礎第24天_Java網路編程續

來源:互聯網
上載者:User

 

                                                          -----------------    
Java培訓  
Android培訓 期待與您的交流----------------------------

 

下面來完成一個傳上傳圖片,這和前面的上傳檔案沒有什麼區別.只不過操作檔案的時候使用的流對象是位元組流而已! 我們來體驗一下!

 

 

//伺服器端public class TcpImage {public static void main(String[] args) throws Exception {ServerSocket server = new ServerSocket(10909);Socket client = server.accept();// 擷取用戶端的輸入資料流InputStream is = client.getInputStream();// 擷取用戶端的輸出資料流OutputStream out = client.getOutputStream();// 檔案存放的位置OutputStream os = new FileOutputStream("server.jpg");byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}// 反饋資訊給用戶端BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));bw.write("圖片上傳完成");bw.flush();os.close();client.close();server.close();}}

 

// 用戶端class Client {public static void main(String[] args) throws Exception {// 建立用戶端服務物件Socket socket = new Socket("192.168.1.102", 10909);InputStream in = new FileInputStream("D:\\imagetest\\desk.jpg");// 擷取用戶端的輸出資料流對象OutputStream os = socket.getOutputStream();// 擷取用戶端的輸入資料流對象InputStream is = socket.getInputStream();byte[] buffIn = new byte[1024];int len = 0;while ((len = in.read(buffIn)) != -1) {os.write(buffIn, 0, len);}// 告訴伺服器我已經發送完畢socket.shutdownOutput();BufferedReader br = new BufferedReader(new InputStreamReader(is));String message = br.readLine();System.out.println(message);in.close();socket.close();}}

我們知道這是單線程,一次只能服務一個用戶端.當用戶端A串連後,被伺服器端擷取到,伺服器執行具體流程,這時B用戶端串連,只能等待,因為伺服器的端還沒有處理完用戶端A的請求,如果很多用戶端都要和我這個伺服器通訊的話,怎麼辦呢?最好伺服器端將每個用戶端封裝到不同的線程裡,這樣就可以處理多個用戶端請求.現在我們來實現一下,多個用戶端實現檔案上傳.
public class TcpThreads implements Runnable {private Socket socket;public TcpThreads(Socket socket) {this.socket = socket;}public void run() {int count = 1;String ip = socket.getInetAddress().getHostAddress();try {System.out.println(ip + "............connected");// 擷取用戶端的輸入資料流File file = new File(ip + ".jpg");// 如果檔案已經存在,則修改名稱使之加一,直到名稱不等while (file.exists())file = new File(ip + "(" + (count++) + ")" + ".jpg");InputStream is = socket.getInputStream();// 擷取用戶端的輸出資料流OutputStream out = socket.getOutputStream();// 檔案存放的位置OutputStream os = new FileOutputStream(file);byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}// 反饋資訊給用戶端BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));bw.write("圖片上傳完成");bw.flush();os.close();socket.close();} catch (Exception e) {throw new RuntimeException(ip + "上傳失敗");}}}

 

class ClientImage {public static void main(String[] args) throws Exception {if (args.length != 1) {System.out.println("請輸入一個檔案有效路徑");return;}File file = new File(args[0]);if (!(file.exists() && file.isFile())) {System.out.println("該檔案已經存在,或者不是一個檔案");return;}long maxSize = 1024 * 1024 * 5;if (file.length() > maxSize) {System.out.println("檔案不能大於5M");return;}if(!file.getName().endsWith(".jpg")){System.out.println("檔案只能是JPG");return;}// 建立用戶端服務物件Socket socket = new Socket("192.168.1.102", 12345);InputStream in = new FileInputStream(file);// 擷取用戶端的輸出資料流對象OutputStream os = socket.getOutputStream();// 擷取用戶端的輸入資料流對象InputStream is = socket.getInputStream();byte[] buffIn = new byte[1024];int len = 0;while ((len = in.read(buffIn)) != -1) {os.write(buffIn, 0, len);}// 告訴伺服器我已經發送完畢socket.shutdownOutput();BufferedReader br = new BufferedReader(new InputStreamReader(is));String message = br.readLine();System.out.println(message);in.close();socket.close();}}

 

class ServerImage {public static void main(String[] args) throws Exception {ServerSocket server = new ServerSocket(12345);while (true) {Socket socket = server.accept();// 阻塞式方法,當擷取到用戶端對象,就建立線程new Thread(new TcpThreads(socket)).start();}}}

 

現在就可以對多個用戶端服務了,看服務端的代碼,while(true)說明伺服器是一直開著的,
public static void main(String[] args) throws Exception {ServerSocket server = new ServerSocket(12345);while (true) {Socket socket = server.accept();// 阻塞式方法,當擷取到用戶端對象,就建立線程new Thread(new TcpThreads(socket)).start();}}

 

又因為accept是阻塞式方法,當沒有用戶端請求伺服器時,伺服器一直處於阻塞狀態,直到有用戶端請求,如果有多個用戶端訪問,也會建立一個新線程為該用戶端服務,因為伺服器處理代碼已經封裝到了run()方法裡面去了!現在實現一個與上面程式類似的小程式,-----TCP 用戶端並發登入 每次看完老師寫完代碼,自己獨立寫出來,一開始總是報一些錯誤,只要自己仔細的分析,問題還是可以解決的,如果老師些一行你寫一行我覺得這樣的效果不好,自己只是,照著他實現了一遍,在腦裡面的印象不是特別的深,如果自己獨立寫出來,雖然可能耗費幾倍的時間,但是已經融入了自己的理解,也提高了自己解決問題的能力.當自己寫完了,再和老師的對照,然後比較那個更好一些!
class ServerLogon implements Runnable {private Socket socket;public ServerLogon(Socket socket) {this.socket = socket;}public void run() {String ip = socket.getInetAddress().getHostAddress();try {//列印用戶端的ipSystem.out.println(ip + "............. connected!");BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);// 只有三次嘗試的機會for (int i = 0; i < 3; i++) {BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("user.txt")));String username = br.readLine();//如果使用者直接退出if (username == null) {break;}String line = null;boolean flag = false;while ((line = reader.readLine()) != null) {if (line.equals(username)) {flag = true;break;}}//如果使用者名稱相同if (flag) {System.out.println(username + "登入成功");pw.println("歡迎登入");}else {System.out.println(username + "嘗試登入");pw.println("無效的使用者名稱");}reader.close();}socket.close();} catch (IOException e) {throw new RuntimeException(ip + "串連失敗");}}}

 

class UserClient {public static void main(String[] args) throws Exception {Socket socket = new Socket("192.168.1.102", 11111);PrintWriter bw = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedReader br = new BufferedReader(new InputStreamReader(System.in));for (int i = 0; i < 3; i++) {String name = br.readLine();System.out.println(name);//如果用戶端按Ctrl+cif (name == null)break;bw.println(name);String message = in.readLine();System.out.println(message);if (message.contains("歡迎")) {break;}}br.close();socket.close();}}

 

public class TcpLogon {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(11111);while (true) {Socket socket = server.accept();new Thread(new ServerLogon(socket)).start();}}}

 

 

 

 

使用者資訊如下所示:

 

我們寫了這麼多的用戶端與服務端,程式不管是多線程還是單線程,它的總體思想是不變的,他們都是和流一起使用的,管伺服器多麼複雜,基本的原理還是這樣的

學好這些,有助於我們以後理解學習和使用伺服器如Tomcat等web伺服器!

 

                          -----------------    
Java培訓   Android培訓 期待與您的交流----------------------------

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.