1. 程式人生 > >Java基礎(十一)

Java基礎(十一)

tcp編程 反射 Java基礎 Javase

(一)TCP編程
(1)TCP(建立連接通道)編程的客戶端的開發步驟

  1)創建客戶端的Socket對象
Socket:就是客戶端的Socket
    構造方法
        public Socket(InetAddress address, int port)
        public Socket(String host, int port):創建客戶端套接字對象,並且指定端口號和ip文本形式

2)獲取通道內的輸出流對象
3)給服務器端寫數據
4)釋放資源
java.net.ConnectException: Connection refused: connect 連接被拒絕
不要先運行客戶端,客戶端的連接需要服務器監聽到才能連接

5)方法

  • public Socket(String host, int port) 創建客戶端的Socket對象
  • public OutputStream getOutputStream():獲取套接字 的輸出流
    (2)服務端的開發步驟:
  • 1)創建服務器端的Socket對象
  • 2)監聽客戶端的連接(阻塞方法)
  • 3)獲取通道內的輸入流
  • 4)讀取數據,顯示控制臺
  • 5)釋放資源
  • java.net.BindException: Address already in use: JVM_Bind 地址被綁定,因為已經有服務器在監聽客戶端連接
    6)方法
  • public ServerSocket(int port) throws IOException創建綁定到特定端口的服務器套接字

監聽客戶端的連接(阻塞方法)

  • public Socket accept(): throws IOException偵聽並接受到此套接字的連接。此方法在連接傳入之前一直阻塞
  • InputStream getInputStream() 獲取通道內的輸入流
  • 獲取ip文本形式‘ :public InetAddress getInetAddress()
  • 服務端不可關閉
    例:客戶端讀取當前項目下的某個文本文件,服務器復制這個文件內容輸出一個新的文本文件(Copy.java)

import java.io.BufferedReader;
import java.io.BufferedWriter;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

//客戶端讀取當前項目下的某個文本文件,服務器復制這個文件內容輸出一個新的文本文件(Copy.java)
/**

  • 按照正常的思路,加入了服務器端反饋操作,發現服務器端的反饋數據,客戶端並沒有收到,客戶端也沒有結束,再等待服務器發送
  • 在客戶端這邊,如果SendDemo.java如果讀完了,服務器端那邊並不知道是否讀完(流是不能使用null作為信息結束條件的,但是客戶端文本文件是可以用null作為信息結束條件的)
  • 服務器等待客戶端通知文本已經讀完了,而客戶端還需要服務器端反饋
  • 解決方案:
  • 1)客戶端這邊,寫一個結束條件,---->服務器如果讀取到了這個結束條件的話,服務器就可以反饋
  • 第一種方式雖然可以解決這種問題,不好,不靈活!
  • 2)public void shutdownOutput():通知服務器端(我沒有數據了,你趕緊反饋)

  • */
    public class UploadClient {

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

    //創建客戶端的Socket對象
    Socket s = new Socket("192.168.10.1",11111); //當前對象創建之後,就會和服務器端建立連接通道
    
    //封裝文本文件
    BufferedReader br = new BufferedReader(
            new FileReader("SendDemo.java")) ;
    
    //封裝通道內的流
    BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(s.getOutputStream())) ;
    //讀寫操作
    String line =null;
    while((line=br.readLine())!=null) {
        bw.write(line);
        bw.newLine();
        bw.flush();
    }
    
    //自定義的結束條件
    /*bw.write("over");
    bw.newLine();
    bw.flush();*/
    
    //通知服務器端,客戶端的文件已經完了,趕緊給反饋
    //public void shutdownOutput():
    s.shutdownOutput(); 
    
    //獲取服務器反饋的數據
    //獲取通道內的字符輸入流
    BufferedReader brClient = new BufferedReader(
            new InputStreamReader(s.getInputStream())) ;
    String client = brClient.readLine() ;
    System.out.println(client);
    
    //釋放資源
    br.close();
    s.close();

    }
    }
    服務端:
    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.net.ServerSocket;
    import java.net.Socket;

//客戶端將文本文件中的數據,復制到服務器端輸出的新的java文件中,然後服務器端要給客戶端反饋數據,客戶端將反饋的數據展示
public class UploadServer {

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

    //服務器端的Socket對象
    ServerSocket ss = new ServerSocket(11111) ;

    //監聽
    Socket s = ss.accept() ;//阻塞

    //封裝通道內的流
    BufferedReader br = new BufferedReader(
            new InputStreamReader(s.getInputStream())) ;

    //封裝最終要輸出的文本文件
    BufferedWriter bw= new BufferedWriter(new FileWriter("Copy.java")) ;

    String line = null ;

    while((line=br.readLine())!=null) {  //阻塞  //通道內的流結束不是用null作為結束條件的

        bw.write(line);
        bw.newLine();
        bw.flush();

    }

    //服務端獲取通道內的輸出流對象
    BufferedWriter bwServer = new BufferedWriter(
            new OutputStreamWriter(s.getOutputStream())) ;
    //向客戶端反饋
    bwServer.write("文件上傳成功了");
    bwServer.newLine(); 
    bwServer.flush();

    //釋放資源
    bw.close();
    s.close();
}

}
(二)反射
(1)什麽是反射:

  • 反射就是通過獲取class字節碼文件對象/Class的類對象,
  • 獲取該字節碼文件對象中的成員變量,構造方法,和成員方法
  • Field: 簡稱成員變量 (Field 提供有關類或接口的單個字段的信息,以及對它的動態訪問權限。
  • 反射的字段可能是一個類(靜態)字段或實例字段。)
    Constructor:簡稱構造方法:提供關於類的單個構造方法的信息以及對它的訪問權限。
    Method:簡稱成員方法:類或接口上單獨某個方法(以及如何訪問該方法)的信息
    (2)獲取字節碼文件
    參數:類路徑:包名.類名
    Class c = Class.forName("類路徑:包名.類名");
    (3)方法
  • public Constructor<?>[] getConstructors():Class 對象所表示的類的所有公共構造方法
  • public Constructor<?>[] getDeclaredConstructors():獲取當前字節碼文件對象中的所有的構造方法
  • 如何獲取單個的構造方法
  • public Constructor<T> getConstructor(Class<?>... parameterTypes)
    //如果是無參的,不用寫;如果是有參的,getContStructor方法中的參數是當前參數類型的靜態屬性class
  • 獲取當前構造的對象; public T newInstance(Object... initargs):initrgs:實際參數
  • 現在獲取的那個構造方法是私有的:public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
  • public void setAccessible(boolean flag):值為 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查
    異常: java.lang.IllegalAccessException: Class org.westos_02.ReflectDemo3 can not access a member of class org.westos_01.Person with modifiers "private at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
  • public Field[] getDeclaredFields():獲取當前字節碼文件對象中所有的字段
  • public Field[] getFields():獲取的是公共的字段
  • public void set(Object obj,Object value)
    參數1:表示給哪個對象設置當前字段的值
    參數2:表示給當前獲取的哪個Field對象的字段設置一個新的值
    java.lang.NoSuchFieldException: name
    name是私有的,必須指定方法獲取
  • public Field getDeclaredField(String name):指定的字段
  • 獲取當前字節碼文件對象中的所有的公共的成員方法(包括父類中的):public Method[] getMethods()
  • public Method[] getDeclaredMethods():所有的成員方法
  • 獲取單個的成員方法,Method
    public Method getMethod(String name, Class<?>... parameterTypes)
    參數1: 表示方法名
    參數2:表示當前方法的參數數據類型的靜態class屬性
  • public Object invoke(Object obj, Object... args)
    參數1:指定的哪個對象上調用底層invoke(),
    參數2:表示的調用那個方法所傳遞的實際參數

Java基礎(十一)