@toc
網絡編程:網絡編程是用來解決計算機和計算機之間的通訊問題;
網頁編程:基於 HDML 頁面的基礎上進行數據的交互;
一、獲取 IP 地址
- IP 類獲取 IP 對象的方式
使用類:InetAddress
常用方法:
方法名 | 含義 |
---|---|
getLocalHost(); | 獲取本機的主機名和 IP 地址 |
getByName(String address); | 可以通過計算機名或者 IP 地址,得到對應的 IP 對象 |
getHostAddress(); | 返回一個 IP 地址的字符串表示方式 |
getHostName(); | 返回主機名 |
以上方法使用示例:
package Demo;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Puzzle4{
public static void main(String[] args) throws UnknownHostException {
//獲取本機的IP地址對象
InetAddress address = InetAddress.getLocalHost();
System.out.println(address);
//通過主機名獲取IP地址
InetAddress address1 = InetAddress.getByName("GJXAIOU");
System.out.println(address1);
InetAddress address2 = InetAddress.getByName("192.168.1.1");
System.out.println(address2);
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
InetAddress[] addresses = InetAddress.getAllByName("www.taobao.com");
for (InetAddress inetAddress : addresses) {
System.out.println(inetAddress);
}
}
}
程序運行結果:
GJXAIOU/192.168.137.1
GJXAIOU/192.168.137.1
/192.168.1.1
192.168.137.1
GJXAIOU
www.taobao.com/61.155.222.102
www.taobao.com/61.155.222.103
二、UDP 中 socket
在網絡編程中所有的數據傳遞都是依賴於 Socket 來完成的,要求進行通信的兩臺計算機都要安裝有 Socket;
不同的傳輸協議有不同的 Socket;
-
UDP 下面的 socket:
1.把數據封裝成一個數據包,面向無連接;
2.UDP 數據報大小限制在 64kB 以內;
3.無連接傳輸速度快但是不可靠;
4.UDP 不區分服務端和客戶端,只有發送端和接收端; -
UDP 下面的 Socket 使用:
- DatagramSocket(); //獲取 UDP 的 Socket
- DatagramPacket(byte[] buf, int length, InetAddress address, int port); //UDP 傳輸的數據包
- buf:要打包的數據,要求數據類型是 byte 類型數組;
- length:要打包數據的字節個數;
- address:發送目標地址的 IP 對象;
- port:端口號
端口號:是系統中每一個執行的程序唯一的編號,接收到的數據根據不同的端口號將數據發送給對應的程序;
序號從 0-65535,其中 0-1023 是爲系統服務的端口號,已經綁定;
- 發送端流程:
- 1.建立 UDP 服務,打開 UDP 協議下的 Socket;
- 2.準備數據;
- 3.將數據打包;
- 4.通過 Socket 發送數據;
- 5.Socket 關閉資源
代碼示例:
- 發送端代碼:
package Demo;
import java.io.IOException;
import java.net.*;
public class Puzzle4{
public static void main(String[] args) throws IOException {
//1.建立UDP服務,打開UDP協議下的Socket,發送端Socket創建不需要任何參數
DatagramSocket socket = new DatagramSocket();
//2.準備數據
String data = "hello";
//3.數據打包
DatagramPacket datagramPacket = new DatagramPacket (data.getBytes(),
data.getBytes().length,
InetAddress.getLocalHost(),
8848);
//4.通過Socket發送數據
socket.send(datagramPacket);
//5.關閉資源
socket.close();
}
}
- 接收端流程:
1.建立UDP服務,監聽端口
2.準備空數據包,用於接收數據
3.調用UDP服務接收數據
4.獲取數據
5.釋放資源
接收端代碼:
package Demo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Puzzle4Receive {
public static void main(String[] args) throws IOException {
//1.建立UDP服務,監聽端口
DatagramSocket socket = new DatagramSocket(8848);
//2.準備空數據包,接收數據
byte[] buf = new byte[1024];
//利用byte數據創建空數據包
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
//3.調用UDP服務,使用Socket接收數據
socket.receive(datagramPacket);
//4.從數據包中獲取socket接收到的數據
//所有的數據都會被保存在byte數組中,通過調用UDP數據包的getlength方法,獲取到接收到的數據字節長度
System.out.println(new String(buf, 0, datagramPacket.getLength()));
//5.關閉資源
socket.close();
}
}
(一)搭建局域網聊天工具
chatSender.java 文件
package Chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* @author GJXAIOU
* @create 2019-07-24-16:02
*/
//這裏使用多線程進行操作
public class chatSender extends Thread {
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket();
//system.in是鍵盤
//這裏是將一個輸入字節流對象做成一個輸入字符流對象,提供給緩衝字符流作爲讀寫的能力
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = null;
DatagramPacket packet = null;
while ((line = bufferedReader.readLine()) != null){
packet = new DatagramPacket(line.getBytes(), line.getBytes().length,
InetAddress.getByName("218.2.216.255"),8888); //裏面的IP地址爲廣播地址
socket.send(packet);
}
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
chatReceive 文件
package Chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* @author GJXAIOU
* @create 2019-07-24-16:02
*/
public class chatReceive extends Thread{
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(8888);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
boolean flag = true;
while (flag){
socket.receive(packet);
System.out.println(packet.getAddress().getHostAddress() + ":" + new String(buf, 0,packet.getLength()));
}
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
chatMain.java 文件
package Chat;
/**
* @author GJXAIOU
* @create 2019-07-24-16:02
*/
public class chatMain {
public static void main(String[] args) {
chatSender chatSender = new chatSender();
chatReceive chatReceive = new chatReceive();
chatSender.start();
chatReceive.start();
}
}
(二)模擬飛秋髮送數據
因此這裏只有發送端程序
package Chat;
import java.io.IOException;
import java.net.*;
/**
* @author GJXAIOU
* @create 2019-07-24-16:45
*/
/*FeiQ的數據格式:
version:time:sender:ip:flag:content
版本號 時間 發送人 IP地址
*/
public class FeiQ {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
String data = getData("hello");
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getByName("192.168.1.1"), 2425);
socket.send(packet);
socket.close();
}
private static String getData(String content){
StringBuilder data = new StringBuilder();
data.append("1.0:");
data.append(System.currentTimeMillis() + ":");
data.append("匿名君");
data.append("10.1.1.1");
data.append("32:");
data.append(content);
return data.toString();
}
}
三、TCP 中 Socket
-
TCP 特徵:
1.TCP 是完全基於 IO 流進行數據傳輸的,面向連接;
2.TCP 進行數據傳遞時候沒有顯示數據報的大;
3.TCP 面向連接,必須通過三次握手之後才能保證數據的傳輸通道是完整的;
4.TCP 面向連接,速度相對較慢;
5.TCP 是區分客戶端和服務器; -
TCP 協議下的 Socket
Socket(服務器 IP 地址對象, 服務器軟件對應的端口號); 創建 TCP 協議下的端口號,並且。。。。
ServerSocket(); 服務器的 Socket,開始服務器服務,準備捕獲 Socket
TCP 客戶端流程:
1.建立 TCP 客戶端連接,申請連接服務器,需要服務器 IP 地址對象和對應的程序端口號;
2.獲取對應的流對象;
3.寫入或者讀取數據;
4.關閉資源;
發送端:
package IP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author GJXAIOU
* @create 2019-07-24-17:11
*/
public class IpSocket {
public static void main(String[] args) throws IOException {
//1.建立客戶端Socket,申請連接服務器,需要服務器的IP地址和對應程序的端口號
Socket socket = new Socket(InetAddress.getLocalHost(), 8000);
//2.發送數據給服務器,需要獲取Socket的輸出流對象
OutputStream os = socket.getOutputStream();
//使用OutputStream方法發送數據到服務器,也就是輸出數據
os.write("你好,服務器".getBytes());
//3.獲取Socket的InputStream
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int length = inputStream.read(buf);
System.out.println("服務器說:" + new String(buf, 0, length));
socket.close();
}
}
服務器接收端:
package IP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author GJXAIOU
* @create 2019-07-24-17:23
*/
public class IpService {
public static void main(String[] args) throws IOException {
//1.使用ServiceSocket開始TCP服務器,監聽指定端口,準備捕獲從客戶端申請Socket連接
ServerSocket serverSocket = new ServerSocket(8000);
//2.接受客戶端連接,得到客戶端Socket對象
Socket accept = serverSocket.accept();
//3.獲取從客戶端得到的Socket對象的輸入流
InputStream inputStream = accept.getInputStream();
byte[] buf = new byte[1024];
int length = inputStream.read(buf);
System.out.println("客戶端說:" + new String(buf, 0, length));
//4.獲取Socket的輸出流對象,給客戶端發送數據
OutputStream outputStream = accept.getOutputStream();
outputStream.write("你好,客戶端:".getBytes());
//關閉ServerSocket,即關閉TCP協議下的服務器程序
serverSocket.close();
}
}