Lesson_for_java_day23--java的網路程式設計練習(登入介面、上傳文件、上傳圖片、通過網路文字轉換)
阿新 • • 發佈:2018-12-31
練習一、模擬賬戶登入介面
服務端:
package Exercise; 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; public class LoginTCPServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10008); while(true){ Socket s = ss.accept(); new Thread(new User(s)).start(); } } } class User implements Runnable{ private Socket s; public User(Socket s) { this.s = s; } public void run() { try { String id = s.getInetAddress().getHostName(); System.out.println(id + "------------connected"); //服務埠的連線可以放在迴圈外 BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter pwOut = new PrintWriter(s.getOutputStream(),true); BufferedReader brFile = null; for(int i = 0; i < 3; i++){ //讀取檔案的輸入流必須每次重新建立,因為上次的輸入已經讀到末尾,如果不重建,讀到的檔案將為空 brFile = new BufferedReader(new FileReader("LoginTCPDemo.txt")); String name = brIn.readLine(); if(name == null) break; String line = null; boolean flag = false; while ((line = brFile.readLine()) != null) { if(line.equals(name)){ flag = true; break; } } if(flag){ System.out.println(name + ": 已經登入"); pwOut.println("歡迎光臨"); break; } else { System.out.println(name + ": 嘗試登入"); pwOut.println("該使用者不存在"); } } System.out.println(id + "server--------close"); s.close(); } catch (Exception e) { throw new RuntimeException("校驗失敗"); } } }
客戶端:
package Exercise; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /* 練習: 客戶端通過鍵盤輸入使用者名稱,服務端對這個使用者名稱進行校驗。 如果該使用者名稱存在,在服務端顯示xxx,已登入,並在使用者端顯示xxx,歡迎光臨 如果該使用者不存在,在服務端顯示xxx,嘗試登入,並在客戶端顯示xxx,該使用者不存在 最多就登入三次。 */ public class LoginTCPClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("192.168.188.1",10008); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter pwOut = new PrintWriter(s.getOutputStream(),true); BufferedReader bfIn = new BufferedReader(new InputStreamReader(s.getInputStream())); for(int i = 0; i < 3 ; i++){ String name = br.readLine(); if(name == null) break; pwOut.println(name); String line = bfIn.readLine(); System.out.println(name + ":" + line); if(line.contains("歡迎")) break; } br.close(); s.close(); } }
練習二、上傳圖片到網路:
服務端:
package Exercise; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; /* 服務端: 這個服務端有個侷限性,當A客戶端連線上以後,被服務端獲取到, 服務端執行具體流程,這時B客戶端連線,只能等待。 因為服務端還沒有處理完A客戶端的請求,還有迴圈回來執行下次 accept方法,所以暫時獲取不到B客戶端物件。 那麼為了可以讓多個客戶端同時併發訪問服務端,服務端最好就是 將每個客戶端封裝到一個單獨的執行緒中,這樣,就可以同時處理多個 客戶端請求。 如何定義執行緒: 只要明確了每個客戶端要在服務端執行的程式碼即可,將該程式碼存入 run方法中。 */ public class PicTCPServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10007); while(true){ Socket s = ss.accept(); new Thread(new PicThread(s)).start(); } } } class PicThread implements Runnable{ private Socket s; public PicThread(Socket s) { this.s = s; } public void run() { int count = 1; String id = s.getInetAddress().getHostName(); try { System.out.println(id + "-----------connected"); BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); File file = new File(id + ".jpg"); while(file.exists()) file = new File(id + "(" + (count++) + ").jpg"); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); byte[] buf = new byte[1024]; int len = 0; System.out.println("Serve------1"); while ((len = bis.read(buf)) != -1) { bos.write(buf,0,len); bos.flush(); } System.out.println("Serve------2"); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bw.write("圖片上傳成功"); System.out.println("Serve------3"); bw.close();//關閉資源很重要,如果不關閉,提醒資訊還在緩衝區,沒有傳送出去,客戶端將出現異常 bos.close(); } catch (Exception e) { throw new RuntimeException(id + "上傳失敗"); } } } /* public class PicTCPServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10007); Socket s = ss.accept(); String id = s.getInetAddress().getHostName(); System.out.println(id + "-----------connected"); BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("2.jpg")); byte[] buf = new byte[1024]; int len = 0; System.out.println("Serve------1"); while ((len = bis.read(buf)) != -1) { bos.write(buf,0,len); bos.flush(); } System.out.println("Serve------2"); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bw.write("圖片上傳成功"); System.out.println("Serve------3"); bw.close();//關閉資源很重要,如果不關閉,提醒資訊還在緩衝區,沒有傳送出去,客戶端將出現異常 bos.close(); ss.close(); } } */
客戶端:
package Exercise;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/*
目的:上傳一張圖片
客戶端:
步驟:
1、建立服務端點。
2、讀取客戶端已有的圖片資料
3、通過Socket輸出流將資料傳送給服務端
4、讀取服務端的反饋資訊。
5、關閉資源
*/
public class PicTCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("192.168.188.1",10007);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] buf = new byte[1024];
System.out.println("Client--------0");
while ((bis.read(buf)) != -1) {
bos.write(buf,0,buf.length);
bos.flush();
}
//告訴服務端資料已經寫完
s.shutdownOutput();
System.out.println("Client--------1");
BufferedReader b = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(b.readLine());
System.out.println("Client--------3");
bis.close();
s.close();
}
}
練習三、上傳檔案到網路:
服務端:
package Exercise;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
//練習:將檔案上傳至服務端,並返回是否上傳成功。
public class TestServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pw = new PrintWriter(new FileWriter("TextTCP.txt"),true);
String line = null;
while ((line = bufIn.readLine()) != null) {
pw.println(line);
}
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write("上傳成功");
bw.close();
pw.close();
s.close();
ss.close();
}
}
客戶端:
package Exercise;
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 TextClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("192.168.188.1",10006);
BufferedReader buf = new BufferedReader(new FileReader("ChatDemo.java"));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
while ((line = buf.readLine()) != null) {
pw.println(line);
}
s.shutdownOutput();//客服端輸出流結束,用於提醒服務端結束接收,防止等待輸入,進入阻塞
BufferedReader b = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(b.readLine());
buf.close();
b.close();
s.close();
}
}
練習四、通過網路進行文字轉換:
服務端:
package Exercise;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
需求:
建立一個文字轉換伺服器,客服端給服務端傳送文字,服務端會將文字轉成大寫再返回給客服端。
而且客服端可以不斷的進行文字轉換,當客服端輸入over時,轉換結束。
分析:服務端:
源:Socket讀取流
目的:Socket輸出流
都是文字,裝飾下。
出現現象:
客服端和服務端都在莫名的等待,這是為什麼呢?
因為客服端和服務端都有阻塞式方法,這些方法沒有讀取到結束標記,那麼就一直等
而導致兩端都在等待。
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//建立服務端
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();//接收連線埠
//測試是否連線成功
String id = s.getInetAddress().getHostName();
System.out.println(id + "..............connected");
//建立網路輸入流
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
//建立網路輸出流
BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
//迴圈獲取資料
while ((line = bufIn.readLine()) != null) {
System.out.println(line);
//注:不用判斷結束語句,如果客服端迴圈結束關閉後,該迴圈也會自動結束
bufOut.write(line.toUpperCase());//將獲取的資料轉換成大寫並返回
//新增換行符,不會導致獲取資料的一方讀完一行後因為沒有讀到換行符而認為讀取資料未結束,而一直處於等待中
bufOut.newLine();
bufOut.flush();//讀取的資料都存放於緩衝區,必須重新整理後才能將資料傳送出去
}
ss.close();//關閉服務端
}
}
客戶端:
package Exercise;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
分析:客服端:
既然是操作裝置上的資料,那麼就可以使用IO技術,並按照IO的操作規律來思考
源:鍵盤錄入
目的:網路輸出流,而且操作的是文字資料,可以選擇字元流
步驟:
1、建立服務
2、獲取鍵盤錄入
3、將資料發給服務端
4、獲取服務端返回的大寫資料
5、結束,關閉資源
都是文字資料,可以使用字元流進行操作,同時提高效率,加入緩衝。
*/
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//建立埠服務
Socket s = new Socket("192.168.188.1",10005);
//獲取鍵盤輸入
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
//建立網路輸出流
BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//建立網路輸入流
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
//鍵盤讀取資料,並將資料傳送出去,然後接收返回資料
while ((line = buf.readLine()) != null) {
if("over".equals(line))
break;
//System.out.println(line);
bufOut.write(line);//讀取的資料以換行符接收,但不包括換行符
//新增換行符,不會導致獲取資料的一方讀完一行後因為沒有讀到換行符而認為讀取資料未結束,而一直處於等待中
bufOut.newLine();
bufOut.flush();//讀取的資料都存放於緩衝區,必須重新整理後才能將資料傳送出去
System.out.println(bufIn.readLine());//接收返回資料,並將資料列印在控制檯上。
}
buf.close();//關閉鍵盤輸入
s.close();//關閉客服端
}
}