網(wǎng)絡(luò)基礎(chǔ)
- 端口號范圍0-65535价认,系統(tǒng)保留0-1023脐彩,常見端口http:80证九,ftp:21妈拌,telnet:23
- socket=ip+端口
- java主要分為InetAdress培愁,URL摹察,Socket(TCP),DatagramSocket(UDP)等類
InetAddress類
InetAddress類沒有構(gòu)造方法,可以通過靜態(tài)方法獲取InetAddress實例對象竿秆。
- 獲取本地主機:getLocalHost()
- 通過主機名獲取實例:getByName(String Host)
- 對實例操作:getHostName()獲取主機名蕾羊,getHostAddress()獲取主機ip地址尼变,getAddress()以字節(jié)數(shù)組的形式返回ip地址
測試:
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class Test{
public static void main(String[] args) throws UnknownHostException{
//獲取本機名
InetAddress address=InetAddress.getLocalHost();
System.out.println(address.getHostName());//輸出主機名
System.out.println(address.getHostAddress());//輸出主機ip地址
byte[] bytes=address.getAddress(); //用字節(jié)數(shù)組表示ip地址
System.out.println(Arrays.toString(bytes));
//通過主機名獲取
InetAddress address2=InetAddress.getByName("你們的大神");//通過名字獲取,name可為主機名或者ip地址
//InetAddress address2=InetAddress.getByName("baidu.com");
//InetAddress address2=InetAddress.getByName("192.168.0.109");
System.out.println(address2.getHostName());
System.out.println(address2.getHostAddress());
byte[] bytes2=address2.getAddress();
System.out.println(Arrays.toString(bytes2));
}
}
URL類
常用構(gòu)造方法:
- URL(String spec)
- URL(String protocol, String host, int port,String file)
- URL(URL context, String spec) 通過已存在的URL構(gòu)建
常用get方法:
getRef()獲取錨點,getQuery()獲取查詢字符串汪诉,getPort()獲取端口號(未指定默認為-1迄本,而瀏覽器默認為80)公条,其他的見測試用例。
測試:
import java.net.MalformedURLException;
import java.net.URL;
public class Test {
public static void main(String[] args) throws MalformedURLException {
URL imooc = new URL("http://www.imooc.com"); // 直接創(chuàng)建
URL url = new URL(imooc, "/index.html?username=tom#test");// 根據(jù)已存在的創(chuàng)建,?表示參數(shù)英上,#表示錨點
System.out.println(url.getProtocol());
System.out.println(url.getHost());
System.out.println(url.getPort()); //如未指定辜纲,則返回-1苍苞;
System.out.println(url.getPath());
System.out.println(url.getFile());
System.out.println(url.getRef()); //錨點
System.out.println(url.getQuery()); //查詢字符串
}
}
結(jié)果:
http
www.imooc.com
-1
/index.html
/index.html?username=tom
test
username=tom
獲取頁面內(nèi)容
使用openStream()獲取字節(jié)輸入流凑耻。
測試:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
//通過URL獲取頁面內(nèi)容
public class Test {
public static void main(String[] args) throws IOException {
URL url=new URL("http://www.baidu.com");
InputStream is=url.openStream();//使用openStream獲取字節(jié)輸入流
InputStreamReader isr=new InputStreamReader(is,"utf-8");//在字節(jié)到字符流時需要指定編碼方式镜盯,避免亂碼
BufferedReader br=new BufferedReader(isr); //添加緩沖流
String data=br.readLine();
while (data!=null){
System.out.println(data);
data=br.readLine();
}
}
}
Socket TCP通信
流程
創(chuàng)建ServerSocket和Socket翅楼,打開輸入輸出流,進行操作讀寫操作,關(guān)閉輸入輸出流美浦,關(guān)閉socket沼沈。
具體
- ServerServer類是服務(wù)端socket艰躺,偵聽客戶端的請求闰蚕。
常用構(gòu)造:ServerSocket(int port)
常用實例方法:accept(),close(),getInetAddress(),getPort() - Socket類是通信的端點。
常用構(gòu)造:Socket(InetAddress address,int port)或Socket(String host,int port)
常用實例方法:getInetAddress(),close()
getInputStream(),getOutputStream(),shutdownInput(),shutdownOutput() - 多線程服務(wù)器专普,可以接受多個客戶端的請求买决,創(chuàng)建一個線程類毅贮,完成對客戶端的操作。
測試
Server.java (服務(wù)器)
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
// 1.創(chuàng)建服務(wù)器ServerSocket茵臭,綁定端口
ServerSocket serverSocket = new ServerSocket(8888);
// 2.使用accept偵聽析恋,偵聽來自客戶端的連接
System.out.println("****服務(wù)器正在啟動漏健,偵聽連接****");
int count=0;
Socket socket;
while (true) {
socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
count++;
System.out.println("client number:"+count);
InetAddress address=socket.getInetAddress();
System.out.println("client address:"+address.getHostAddress());
}
// serverSocket.close();不會執(zhí)行到這一步,一直循環(huán)处窥,去掉該語句摊阀。
}
}
ServerThread.java (服務(wù)器線程)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread {
Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr); // 添加緩沖流
String data = null;
while ((data = br.readLine()) != null) {
System.out.println("我是服務(wù)端顿涣,客戶端說:" + data);
}
socket.shutdownInput(); // 關(guān)閉socket的輸入流
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("hello");
pw.flush();
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (pw != null)
pw.close();
if (os != null)
os.close();
if (br != null)
br.close();
if (isr != null)
isr.close();
if (is != null)
is.close();
if (socket != null)
socket.close();
} catch (IOException e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}
Client.java (客戶端)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.創(chuàng)建客戶端socket精堕,指定服務(wù)器地址和端口
Socket socket=new Socket("localhost", 8888);//本地服務(wù)器的8888端口
//2. 獲取輸出流蒲障,發(fā)送信息
OutputStream os=socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);
pw.write("admin:456");
pw.flush();
socket.shutdownOutput();
// 3. 獲取輸入流,接收信息
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr); //添加緩沖流
String data=null;
while((data=br.readLine())!=null){
System.out.println("我是客戶端庄撮,服務(wù)端說:"+data);
}
socket.shutdownInput(); //關(guān)閉socket的輸入流
//3.關(guān)閉資源
is.close();
isr.close();
br.close();
pw.close();
os.close();
socket.close();
}
}
Socket UDP通信
流程
客戶端和服務(wù)器創(chuàng)建DatagramPacket保存相應(yīng)數(shù)據(jù)毙籽,創(chuàng)建DatagramSocket,使用DatagramSocket實例的send(),receive()方法來進行通信
具體
- DatagramPacket類是UDP用來發(fā)送的數(shù)據(jù)報烙如,UDP無連接垮衷,所以數(shù)據(jù)中可以包含ip地址,端口號等刀闷。另外,需要另外定義一個byte[]類型的數(shù)組甸昏,用來存放數(shù)據(jù),這個數(shù)組與DatagramPacket實例實質(zhì)上是同一個卒蘸。
- DatagramSocket類是用來發(fā)送或者接受數(shù)據(jù)報的翻默,主要使用該實例的receive(DatagramPacket packet)和send(DatagramPacket packet)方法,分別把數(shù)據(jù)存放在packet中的數(shù)組中(自己另外定義的)趾牧,以及相關(guān)信息肯污。
- 也可以用多線程服務(wù)器。
測試
UDPserver.java(UDP服務(wù)器)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args) throws IOException {
// 1. 創(chuàng)建服務(wù)器端datagramsocket哄芜,指定端口
DatagramSocket socket = new DatagramSocket(8800);
// 2. 創(chuàng)建數(shù)據(jù)報柬唯,用于接受客戶端發(fā)送的數(shù)據(jù)
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, 0, data.length);
// 3.接受客戶端發(fā)送的數(shù)據(jù),存放在packet
System.out.println("***服務(wù)器正在啟動***");
socket.receive(packet);
// 4.讀取數(shù)據(jù)
String info = new String(data, 0, packet.getLength());
System.out.println("i'm server,client say:" + info);
// 數(shù)據(jù),發(fā)送至客戶端
// 1.得到客戶端地址美尸,端口斟薇,數(shù)據(jù)
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "hello".getBytes();
// 2.創(chuàng)建數(shù)據(jù)報
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
// 3.響應(yīng)客戶端
socket.send(packet2);
// 4.關(guān)閉資源
socket.close();
}
}
UDPclient(客戶端)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args) throws IOException {
// 1.定義服務(wù)器的地址堪滨,端口,數(shù)據(jù)
InetAddress address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "admin:123".getBytes();
// 2.創(chuàng)建數(shù)據(jù)報袱箱,包含信息
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
// 3.創(chuàng)建DatagramSocket對象
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
// 接受來自服務(wù)器數(shù)據(jù)
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2, 0, data2.length);
// 3.接受客戶端發(fā)送的數(shù)據(jù),存放在packet
socket.receive(packet2);
// 4.讀取數(shù)據(jù)
String info = new String(data2, 0, packet2.getLength());
System.out.println("i'm client,server say:" + info);
}
}