import java.net.InetAddress;
import java.net.UnknownHostException;
/*
網絡:兩台或多台裝置通過一定實體裝置連接配接起來構成了網絡
根據網絡覆寫範圍不同,可分為:
區域網路:覆寫範圍最小,僅僅覆寫一個教室或一個機房
域域網:覆寫範圍較大,可以覆寫一個城市
廣域網:覆寫範圍最大,可以覆寫全國甚至全球,如網際網路
IP位址:用于唯一辨別網絡中的每台計算機
檢視IP位址:ipconfig
IP位址的表示形式:點分十進制 xx.xx.xx.xx ,每個十進制的範圍:0--255
對于IPV4 4個位元組(32位)表示,一個位元組的範圍0--255
IP位址的組成:網絡位址+主機位址 如192.168.1.106
IPV6是網際網路工程任務設計的用于替代IPV4的下一代IP協定,IPV6使用128位表示位址,是IPV4的4倍,點分十進制不再适用
用冒分十六進制,0位壓縮,内嵌IPV4位址等方法表示
域名:将IP位址映射成域名,如www.csdn.net
端口号:用于辨別計算機上某個特定的網絡程式
表示形式:以整數形式,範圍0~65535,0~1024已被占用
常見網絡程式端口:
tomcat 8080,mysql 3306,oracle 1521,sqlserver 1433
協定
TCP/IP,中文譯名為傳輸控制協定/網際網路互聯協定,是Internet最基本的協定
網絡通信協定
OSI模型 TCP/IP模型 TCP/IP模型各層對應協定
應用層 應用層 HTTP,ftp,teInet,DNS..
表示層 應用層
會話層 應用層
傳輸層 傳輸層(TCP) TCP,UDP,....
網絡層 網絡層(IP) IP,ICMP,ARP.....
資料鍊路層 實體+資料鍊路層 Link
實體層 實體+資料鍊路層
TCP協定
1.使用協定前,需建立TCP連接配接,形成傳輸資料通道
2.傳輸前,采用"三次握手"方式,是可靠的
3.TCP協定進行通信的兩個應用程序:用戶端、服務端
4.在連接配接中可進行大資料量傳輸
5.傳輸完畢需釋放已建立的連接配接,效率低
UDP協定
1.将資料、源、目的封裝成資料包,不需建立連接配接
2.每個資料包的大小限制在64K内
3.無需連結,是以不可靠
4.發送資料結束時無需釋放資源,效率高
InetAddress類
相關方法
getLocalHost //擷取本機InetAddress對象
getByName //根據指定主機名/域名擷取IP位址對象
getHostName //擷取InetAddress對象的主機名
getHostAddress //通過InetAddress對象擷取位址
*/
// 示範InetAddress類的使用
public class network_ {
public static void main(String[] args) throws UnknownHostException {
//擷取本機InetAddress對象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);//計算機名+IP位址
//根據指定主機名/域名擷取IP位址對象
InetAddress host = InetAddress.getByName("huang");
System.out.println(host);//計算機名+IP位址
//根據域名傳回InetAddress對象,如輸入csdn域名
InetAddress host2 = InetAddress.getByName("www.csdn.net");
System.out.println(host2);//www.csdn.net/60.205.172.2
//擷取InetAddress對象的主機名
String hostName = host2.getHostName();
System.out.println(hostName);//www.csdn.net
//通過InetAddress對象擷取位址
String hostAddress = host2.getHostAddress();
System.out.println(hostAddress);//60.205.172.2
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
Socket
1.套接字(Socket)開發網絡應用程式被廣泛應用,成為事實上的标準
2.通信的兩端都要有Socket,是兩台機器間通信的端點
3.網絡通信其實就是Socket間的通信
4.Socket允許程式把網絡連接配接當成一個流,資料在兩個Socket間通過IO傳輸
5.一般主動發起通信的應用屬用戶端,等待通信請求的為服務端
讀寫資料
socket.getOutputStream()
socket.getInputStream()
TCP網絡通信程式設計
1.基于用戶端——服務端的網絡通信
2.底層使用的是TCP/IP協定
設定結束标記
socket.shutdownOutput();
*/
/* 編寫一個服務端和一個用戶端,伺服器端在9999端口監聽
用戶端連接配接到伺服器端,發送hello,server,并接收伺服器端回發的hello,client,之後退出
伺服器端接收到用戶端發送的資訊,輸出并發送hello,client,之後退出
*/
// 服務端(位元組流)
@SuppressWarnings({"all"})
public class TCP_Server {
public static void main(String[] args) throws IOException {
//1. 在本機 的 9999 端口監聽, 等待連接配接
// 要求在本機沒有其它服務在監聽 9999
// ServerSocket 可以通過 accept() 傳回多個 Socket[多個用戶端連接配接伺服器的并發]
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服務端,在 9999 端口監聽,等待連接配接..");
//2. 當沒有用戶端連接配接 9999 端口時,程式會 阻塞, 等待連接配接
// 如果有用戶端連接配接,則會傳回 Socket 對象,程式繼續
Socket socket = serverSocket.accept();
System.out.println("服務端 socket =" + socket.getClass());
//3. 通過 socket.getInputStream() 讀取用戶端寫入到資料通道的資料, 顯示
InputStream inputStream = socket.getInputStream();
//4. IO 讀取
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));//根據讀取到的實際長度,顯示内容
}
//5. 擷取 socket 相關聯的輸出流
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello, client".getBytes());
// 設定結束标記
socket.shutdownOutput();
//6.關閉流和 socket
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();//關閉
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
// 用戶端(位元組流)
@SuppressWarnings({"all"})
public class TCP_Client {
public static void main(String[] args) throws IOException {
//1. 連接配接服務端 (ip , 端口)
// 連接配接本機的 9999 端口, 如果連接配接成功,傳回 Socket 對象
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("用戶端 socket 傳回=" + socket.getClass());
//2. 連接配接上後,生成 Socket, 通過 socket.getOutputStream()
// 得到 和 socket 對象關聯的輸出流對象
OutputStream outputStream = socket.getOutputStream();
//3. 通過輸出流,寫入資料到 資料通道
outputStream.write("hello, server".getBytes());
// 設定結束标記
socket.shutdownOutput();
//4. 擷取和 socket 關聯的輸入流. 讀取資料(位元組),并顯示
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
//5. 關閉流對象和 socket, 必須關閉
inputStream.close();
outputStream.close();
socket.close();
System.out.println("用戶端退出.....");
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
// 服務端(字元流)
@SuppressWarnings({"all"})
public class TCP_Server02 {
public static void main(String[] args) throws IOException {
//1. 在本機 的 9999 端口監聽, 等待連接配接
// 要求在本機沒有其它服務在監聽 9999
// ServerSocket 可以通過 accept() 傳回多個 Socket[多個用戶端連接配接伺服器的并發]
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服務端,在 9999 端口監聽,等待連接配接..");
//2. 當沒有用戶端連接配接 9999 端口時,程式會 阻塞, 等待連接配接
// 如果有用戶端連接配接,則會傳回 Socket 對象,程式繼續
Socket socket = serverSocket.accept();
System.out.println("服務端 socket =" + socket.getClass());
//3. 通過 socket.getInputStream() 讀取用戶端寫入到資料通道的資料, 顯示
InputStream inputStream = socket.getInputStream();
//4. IO 讀取
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println(s);
//5. 擷取 socket 相關聯的輸出流
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello,client");
bufferedWriter.newLine();//插入換行符,表示内容結束
bufferedWriter.flush();//使用字元流,需要手動重新整理,否則資料不會寫入資料通道
// 設定結束标記
socket.shutdownOutput();
//6.關閉流和 socket
bufferedReader.close();
bufferedWriter.close();
socket.close();
serverSocket.close();//關閉
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
// 用戶端(位元組流)
@SuppressWarnings({"all"})
public class TCP_Client02 {
public static void main(String[] args) throws IOException {
//1. 連接配接服務端 (ip , 端口)
// 連接配接本機的 9999 端口, 如果連接配接成功,傳回 Socket 對象
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("用戶端 socket 傳回=" + socket.getClass());
//2. 連接配接上後,生成 Socket, 通過 socket.getOutputStream()
// 得到 和 socket 對象關聯的輸出流對象
OutputStream outputStream = socket.getOutputStream();
//3. 通過輸出流,寫入資料到 資料通道
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello,server");
bufferedWriter.newLine();//插入換行符,表示寫入内容結束,即結束标記,要求對方使用readLine()
bufferedWriter.flush();//使用字元流,需要手動重新整理,否則資料不會寫入資料通道
//4. 擷取和 socket 關聯的輸入流. 讀取資料(位元組),并顯示
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println(s);
//5. 關閉流對象和 socket, 必須關閉
bufferedWriter.close();//關閉外層流
bufferedReader.close();
socket.close();
System.out.println("用戶端退出.....");
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
// 服務端(字元流)
@SuppressWarnings({"all"})
public class TCP_Server02 {
public static void main(String[] args) throws IOException {
//1. 在本機 的 9999 端口監聽, 等待連接配接
// 要求在本機沒有其它服務在監聽 9999
// ServerSocket 可以通過 accept() 傳回多個 Socket[多個用戶端連接配接伺服器的并發]
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服務端,在 9999 端口監聽,等待連接配接..");
//2. 當沒有用戶端連接配接 9999 端口時,程式會 阻塞, 等待連接配接
// 如果有用戶端連接配接,則會傳回 Socket 對象,程式繼續
Socket socket = serverSocket.accept();
System.out.println("服務端 socket =" + socket.getClass());
//3. 通過 socket.getInputStream() 讀取用戶端寫入到資料通道的資料, 顯示
InputStream inputStream = socket.getInputStream();
//4. IO 讀取
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println(s);
//5. 擷取 socket 相關聯的輸出流
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello,client");
bufferedWriter.newLine();//插入換行符,表示内容結束
bufferedWriter.flush();//使用字元流,需要手動重新整理,否則資料不會寫入資料通道
// 設定結束标記
socket.shutdownOutput();
//6.關閉流和 socket
bufferedReader.close();
bufferedWriter.close();
socket.close();
serverSocket.close();//關閉
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
// 用戶端
public class TCP_Client03 {
public static void main(String[] args) throws Exception {
//用戶端連接配接服務端
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//建立讀取磁盤檔案的輸入流
String filePath = "d:\\demo.png";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
//bytes就是filePath對應的位元組數組
byte[] bytes = StreamUtils.streamToByteArray(bis);
//通過socket擷取到輸出流,将bytes發送給服務端
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
//将檔案對應的位元組數組寫入對應的資料通道
bos.write(bytes);
bis.close();
//設定寫入資料的結束标記
socket.shutdownOutput();
//接收服務端回複的消息
InputStream inputStream = socket.getInputStream();
//使用Utils方法将inputStream轉成字元串
String s = StreamUtils.streamToString(inputStream);
System.out.println(s);
//關流
inputStream.close();
bos.close();
socket.close();
}
}
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
//此類用于示範關于流的讀寫方法
public class StreamUtils {
// 将輸入流轉換成byte[]
public static byte[] streamToByteArray(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();//建立輸出流對象
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
bos.write(b, 0, len);
}
byte[] array = bos.toByteArray();
bos.close();
return array;
}
// 将InputStream轉換成String
public static String streamToString(InputStream is) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder= new StringBuilder();
String line;
while((line=reader.readLine())!=null){ //當讀取到 null時,就表示結束
builder.append(line+"\r\n");
}
return builder.toString();
}
}
/*
netstat指令
netstat-an 檢視目前主機網絡情況,包括端口監聽和網絡連接配接情況
netstat-an|more 分頁顯示
要求在dos控制台下執行
Listening 表示某個端口在監聽
如果有一個外部程式(用戶端)連接配接到該端口,就會顯示一條連接配接資訊
可以輸入ctrl+c退出指令
當用戶端連接配接到服務端後,實際上用戶端也是通過一個端口和服務端進行通訊的,這個端口是TCP/IP來配置設定的,是不确定的,随機的
*/