------<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="blank">Java教育訓練、Android教育訓練、iOS教育訓練、.Net教育訓練</a>、期待與您交流! -------
一.IP位址
每個裝置在網絡中的唯一辨別
每台網絡終端在網絡中都有一個獨立的位址,我們在網絡中傳輸資料就是使用這個位址。
ipconfig:檢視本機IP
ping:測試連接配接
本地回路位址:127.0.0.1255.255.255.255是廣播位址
IPv4:4個位元組組成,4個0-255。大概42億,30億都在北美,亞洲4億。2011年初已經用盡。
IPv6:8組,每組4個16進制數。
1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
1a2b::aaaa:0000:0000:0000:aabb:1f2f
1a2b:0000:aaaa::aabb:1f2f
1a2b:0000:aaaa::0000:aabb:1f2f
1a2b:0000:aaaa:0000::aabb:1f2f
二.端口号
每個程式在裝置上的唯一辨別
每個網絡程式都需要綁定一個端口号,傳輸資料的時候除了确定發到哪台機器上,還要明确發到哪個程式。
端口号範圍從0-65535
編寫網絡應用就需要綁定一個端口号,盡量使用1024以上的,1024以下的基本上都被系統程式占用了。
常用端口
mysql: 3306
oracle: 1521
web: 80
tomcat: 8080
QQ: 4000
feiQ: 2425
三.網絡協定
為計算機網絡中進行資料交換而建立的規則、标準或約定的集合。
UDP
面向無連接配接,資料不安全,速度快。不區分用戶端與服務端。
TCP
面向連接配接(三次握手),資料安全,速度略低。分為用戶端和服務端。
三次握手: 用戶端先向服務端發起請求, 服務端響應請求, 傳輸資料
四.Socket
通信的兩端都有Socket。
網絡通信其實就是Socket間的通信。
資料在兩個Socket間通過IO流傳輸。
Socket在應用程式中建立,通過一種綁定機制與驅動程式建立關系,告訴自己所對應的IP和port。
五.UDP傳輸
1.發送
建立DatagramSocket, 随機端口号
建立DatagramPacket, 指定資料, 長度, 位址, 端口
使用DatagramSocket發送DatagramPacket
關閉DatagramSocket
2.接收
建立DatagramSocket, 指定端口号
建立DatagramPacket, 指定數組, 長度
使用DatagramSocket接收DatagramPacket
關閉DatagramSocket
從DatagramPacket中擷取資料
3.接收方擷取ip和端口号
String ip =packet.getAddress().getHostAddress();
int port = packet.getPort();
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
public class Demo2_Send {
/**
* 1.發送 建立DatagramSocket, 随機端口号 建立DatagramPacket, 指定資料, 長度, 位址, 端口
* 使用DatagramSocket發送DatagramPacket 關閉DatagramSocket
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// String str = "我讀書少,你不要騙我";
DatagramSocket socket = new DatagramSocket(); // 建立Socket對象,相當于建立碼頭
Scanner sc = new Scanner(System.in);
while (true) {
String line = sc.nextLine();
if("quit".equals(line))
break;
DatagramPacket packet = // 建立Packet對象,相當于建立集裝箱
new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("127.0.0.1"), 6666);
socket.send(packet); // 發送集裝箱
}
socket.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Demo2_Receive {
/**
* 2.接收
建立DatagramSocket, 指定端口号
建立DatagramPacket, 指定數組, 長度
使用DatagramSocket接收DatagramPacket
關閉DatagramSocket
從DatagramPacket中擷取資料
* @throws IOException
*/
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(6666); //建立Socket對象,相當于建立碼頭
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//建立Packet對象,相當于建立集裝箱接貨
while(true) {
socket.receive(packet); //接收資料
byte[] arr = packet.getData(); //擷取資料
int len = packet.getLength(); //擷取有效的位元組個數
String ip = packet.getAddress().getHostAddress(); //擷取ip位址
System.out.println(ip + ":" + new String(arr,0,len));
}
}
}
多線程
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Demo3_MoreThread {
/**
* @param args
*/
public static void main(String[] args) {
new Receive().start();
new Send().start();
}
}
class Receive extends Thread {
public void run() {
try {
DatagramSocket socket = new DatagramSocket(6666); //建立Socket對象,相當于建立碼頭
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//建立Packet對象,相當于建立集裝箱接貨
while(true) {
socket.receive(packet); //接收資料
byte[] arr = packet.getData(); //擷取資料
int len = packet.getLength(); //擷取有效的位元組個數
String ip = packet.getAddress().getHostAddress(); //擷取ip位址
System.out.println(ip + ":" + new String(arr,0,len));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Send extends Thread {
public void run() {
try {
DatagramSocket socket = new DatagramSocket(); // 建立Socket對象,相當于建立碼頭
Scanner sc = new Scanner(System.in);
while (true) {
String line = sc.nextLine();
if("quit".equals(line))
break;
DatagramPacket packet = // 建立Packet對象,相當于建立集裝箱
new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.33.186"), 6666);
socket.send(packet); // 發送集裝箱
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
六.TCP傳輸
1.用戶端
建立Socket連接配接服務端(指定ip位址,端口号)通過ip位址找對應的伺服器
調用Socket的getInputStream()和getOutputStream()方法擷取和服務端相連的IO流
輸入流可以讀取服務端輸出流寫出的資料
輸出流可以寫出資料到服務端的輸入流
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.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Demo2_Client {
/**
*1.用戶端
建立Socket連接配接服務端(指定ip位址,端口号)通過ip位址找對應的伺服器
調用Socket的getInputStream()和getOutputStream()方法擷取和服務端相連的IO流
輸入流可以讀取服務端輸出流寫出的資料
輸出流可以寫出資料到服務端的輸入流
* @throws Exception
* @throws UnknownHostException
*/
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 12345); //建立用戶端
/*InputStream is = socket.getInputStream(); //擷取輸入流
OutputStream os = socket.getOutputStream(); //擷取輸出流
byte[] arr = new byte[1024];
int len = is.read(arr); //讀取伺服器發送的資料
System.out.println(new String(arr,0,len));
os.write("學習挖掘機哪家強".getBytes()); //将資料寫給伺服器
*/
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//包裝位元組輸入流
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());//包裝位元組輸出流
System.out.println(br.readLine()); //讀取伺服器寫過來的内容
ps.println("我要報名就業班"); //将資料寫給伺服器
System.out.println(br.readLine())
ps.println("不學了");
//bw.write("我要報名就業班");
socket.close();
}
}
2.服務端
建立ServerSocket(需要指定端口号)
調用ServerSocket的accept()方法接收一個用戶端請求,得到一個Socket
調用Socket的getInputStream()和getOutputStream()方法擷取和用戶端相連的IO流
輸入流可以讀取用戶端輸出流寫出的資料
輸出流可以寫出資料到用戶端的輸入流
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.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Demo2_Server {
/**
* 2.服務端
建立ServerSocket(需要指定端口号)
調用ServerSocket的accept()方法接收一個用戶端請求,得到一個Socket
調用Socket的getInputStream()和getOutputStream()方法擷取和用戶端相連的IO流
輸入流可以讀取用戶端輸出流寫出的資料
輸出流可以寫出資料到用戶端的輸入流
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(54321); //建立服務端,綁定54321端口
Socket socket = server.accept(); //接受用戶端請求
/*InputStream is = socket.getInputStream(); //擷取位元組輸入流
OutputStream os = socket.getOutputStream(); //擷取位元組輸出流
os.write("百度一下你就知道".getBytes()); //将内容寫給用戶端
byte[] arr = new byte[1024];
int len = is.read(arr); //從用戶端讀取資料
System.out.println(new String(arr,0,len)); */
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//包裝位元組輸入流
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//bw.write("歡迎咨詢傳智播客");
PrintStream ps = new PrintStream(socket.getOutputStream());//包裝位元組輸出流,因為裡面有一個println的方法
ps.println("歡迎咨詢傳智播客"); //将字元串寫到用戶端
System.out.println(br.readLine()); //讀取用戶端發過來的資訊
ps.println("報滿了,等下一期吧");
System.out.println(br.readLine());
server.close();
socket.close();
}
}
建立多線程的服務端,可以不斷的向服務端通路
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Demo3_MoreThread {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
while(true) {
final Socket socket = server.accept(); //不斷的接收用戶端的請求
new Thread() {
public void run() {
try {
BufferedReader br =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("歡迎咨詢黑馬程式員");
System.out.println(br.readLine());
ps.println("不一萬就業不給一分錢");
System.out.println(br.readLine());
ps.println("不學拉到");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
}
七.反射
1.Class
.class檔案加載到記憶體中就是一個Class對象
擷取Class對象的方式有3種:
Scanner sc = newScanner("xxx.txt");
Class.forName(sc.nextLine());
類名.class
對象.getClass()
import cn.itcast.bean.Person;
public class Demo1_Reflect {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz1 = Class.forName("cn.itcast.bean.Person");
Class<?> clazz2 = Person.class;
Person p = new Person();
Class<?> clazz3 = p.getClass();
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);
}
}
2.Constructor
Class類的newInstance()方法是使用該類無參的構造函數建立對象, 如果一個類沒有無參的構造函數, 就不 能這樣建立了
可以調用Class類的getConstructor(String.class,int.class)方法擷取一個指定的構造函數
然後再調用Constructor類的newInstance("張三",20)方法建立對象
import java.lang.reflect.Constructor;
import cn.itcast.bean.Person;
public class Demo3_Constructor {
/*
@throws Exception
*/
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
/*Person p = (Person) clazz.newInstance();
System.out.println(p);*/
Constructor con = clazz.getConstructor(String.class,int.class);//擷取有參的構造函數
Person p = (Person) con.newInstance("張三",23); //建立對象
System.out.println(p); //列印對象
}
}
3.Field
Class.getField(String)方法可以擷取類中的指定字段(可見的), 如果是私有的可以用getDeclaedField("name")方法擷取
通過set(obj, "李四")方法可以設定指定對象上該字段的值, 如果是私有的需要先調用setAccessible(true)設定通路權限
用擷取的指定的字段調用get(obj)可以擷取指定對象中該字段的值
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import cn.itcast.bean.Person;
public class Demo4_Field {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
Constructor con = clazz.getConstructor(String.class,int.class);//擷取有參的構造函數
Person p = (Person) con.newInstance("張三",23); //建立對象
/*Field f = clazz.getField("name");
System.out.println(f);*/
Field f = clazz.getDeclaredField("name"); //暴力反射
f.setAccessible(true); //去除權限
f.set(p, "李四");
System.out.println(p);
}
4.Method
Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以擷取類中 的指定方法
調用invoke(Object,Object...)可以調用該方法
Class.getMethod("eat")invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import cn.itcast.bean.Person;
public class Demo5_Method {
/**
*4.Method
Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以擷取類中的指定方法
調用invoke(Object, Object...)可以調用該方法
Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
Constructor con = clazz.getConstructor(String.class,int.class);//擷取有參的構造函數
Person p = (Person) con.newInstance("張三",23); //建立對象
Method m = clazz.getMethod("eat");
m.invoke(p);
Method m2 = clazz.getMethod("eat", int.class);
m2.invoke(p, 10);
}
}