1 網絡要素(IP地址、端口號、傳輸協議)
IP地址:InetAddress
網絡中設備的標識
不易記憶,可用主機名
本地迴環地址:127.0.0.1 主機名:localhost
端口號:
用於標識進程的邏輯地址,不同進程的標識
有效端口:0~65535,其中0~1024系統使用或保留端口。
傳輸協議:通訊的規則常見協議:TCP,UDP
UDP
將數據及源和目的封裝成數據包中,不需要建立連接
每個數據報的大小在限制在64k內
因無連接,是不可靠協議
不需要建立連接,速度快
TCP(傳輸控制協議)
建立連接,形成傳輸數據的通道。
在連接中進行大數據量傳輸
通過三次握手完成連接,是可靠協議
必須建立連接,效率會稍低
2 IP對象 InetAddress
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPDemo {
public static void main(String[] args) throws UnknownHostException {
//UnknownHostException未知主機異常
//獲取本地主機ip地址對象
InetAddress ip = InetAddress.getLocalHost();
System.out.println(ip.getHostName()+":"+ip.getHostAddress());
//獲取其他主機的ip地址對象
ip = InetAddress.getByName("www.baidu.com");
//獲取主機ip地址
System.out.println(ip.getHostAddress());
//獲取主機名
System.out.println(ip.getHostName());
}
}
域名解析:
就是通過主機名(域名或者網址),在DNS服務器(域名解析服務器)中找到相應的ip地址,返回,最終才能訪問所指定的網址 通常由寬帶服務商指定DNS服務器
3 TCP協議
客戶端發數據到服務端
Tcp傳輸,客戶端建立的過程:
1、創建tcp客戶端socket服務。使用的是Socket對象。建議該對象一創建就明確目的地。要連接的主機。
2、如果連接建立成功,說明數據傳輸通道已建立。該通道就是socket流 ,是底層建立好的。 既然是流,說明這裏既有輸入,又有輸出。想要輸入或者輸出流對象,可以找Socket來獲取。 可以通過getOutputStream(),和getInputStream()來獲取兩個字節流。
3、使用輸出流,將數據寫出。
4、關閉資源。
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientDemo {
public static void main(String[] args) throws UnknownHostException, IOException {
//創建客戶端socket服務。
Socket socket = new Socket("127.0.0.1",10002);
//獲取socket流中的輸出流。
OutputStream out = socket.getOutputStream();
//使用輸出流將指定的數據寫出去。
out.write("tcp演示:哥們又來了!".getBytes());
//關閉資源。
socket.close();
}
}
建立tcp服務端的思路:
1、創建服務端socket服務。通過ServerSocket對象。
2、服務端必須對外提供一個端口,否則客戶端無法連接。
3、獲取連接過來的客戶端對象。
4、通過客戶端對象獲取socket流讀取客戶端發來的數據 並打印在控制檯上。
5、關閉資源。關客戶端,關服務端。
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
//1創建服務端對象。
ServerSocket ss = new ServerSocket(10002);
//2,獲取連接過來的客戶端對象。
Socket s = ss.accept();//阻塞式.
String ip = s.getInetAddress().getHostAddress();
//3,通過socket對象獲取輸入流,要讀取客戶端發來的數據
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(ip+":"+text);
s.close();
ss.close();
}
}
4 UDP協議
創建UDP傳輸的發送端 :
1、建立udp的socket服務
2、將要發送的數據封裝到數據包中
3、通過udp的socket服務 將數據包發送出去
4、關閉socket服務(因爲調用了系統的底層資源網卡)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSendDemo {
public static void main(String[] args) throws IOException {
System.out.println("發送端啓動.......");
//1.udp的socket服務,使用DatagramSocket對象
DatagramSocket ds = new DatagramSocket();
//2.將要發送的數據封裝到數據包中
String str = "哥們來啦!";
//使用DatagramPacket將數據封裝到該對象包中
byte[] buf = str.getBytes();
DatagramPacket dp =
new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10000);
//通過udp的socket服務將數據包發送出去,使用send方法
ds.send(dp);
//關閉資源
ds.close();
}
}
1、建立udp socket服務,因爲要接受數據,所以必須要明確端口號
2、創建數據包,用於存儲接收到的數據,方便用於數據包對象的方法解析這些數據
3、使用socket服務的receive方法將接收到的數據存儲到數據包中,
4、通過數據包的方法解析數據包中的數據
5、關閉資源
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDPReceiveDemo {
public static void main(String[] args) throws IOException {
System.out.println("接收端啓動.......");
//1.建立udp socket服務
DatagramSocket ds = new DatagramSocket(10000);
//2.創建數據包,用於存儲接受到到的數據
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//3.使用接收方法將數據存儲在數據包中
ds.receive(dp);//阻塞式的方法,沒有數據會等待
//4.通過數據包對象的方法,解析其中的數據,比如:地址,端口,數據內容
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+":"+text);
//5.關閉資源
ds.close();
}
}
5 UDP協議練習-聊天程序
發送端:(將數據源改爲鍵盤錄入)import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSendDemo {
public static void main(String[] args) throws IOException {
System.out.println("發送端啓動.......");
//1.udp的socket服務,使用DatagramSocket對象
DatagramSocket ds = new DatagramSocket();
//2.將要發送的數據封裝到數據包中
//使用DatagramPacket將數據封裝到該對象包中
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine())!=null){
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10000);
ds.send(dp);
if("over".equals(line))
break;
}
ds.close();
}
}
接收端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceiveDemo {
public static void main(String[] args) throws IOException {
System.out.println("接收端啓動.......");
//1.建立udp socket服務
DatagramSocket ds = new DatagramSocket(10000);
while(true){
//2.創建數據包
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//3.使用接收方法將數據存儲在數據包中
ds.receive(dp);
//4.通過數據包對象的方法,解析其中的數據,比如:地址,端口,數據內容
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+":"+text);
}
//5.關閉資源
//ds.close();
}
}
Send.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null){
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10001);
ds.send(dp);
if("886".equals(line))
break;
}
ds.close();
} catch (Exception e) {
}
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while (true) {
// 2,創建數據包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 3,使用接收方法將數據存儲到數據包中。
ds.receive(dp);// 阻塞式的。
// 4,通過數據包對象的方法,解析其中的數據,比如,地址,端口,數據內容。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + "::" + text);
if(text.equals("886")){
System.out.println(ip+"....退出聊天室");
}
}
} catch (Exception e) {
}
}
}
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
DatagramSocket send = new DatagramSocket();
DatagramSocket rece = new DatagramSocket(10001);
new Thread(new Send(send)).start();
new Thread(new Rece(rece)).start();
}
}