一.初始網(wǎng)絡編程
1.什么是網(wǎng)絡編程
計算機跟計算機之間通過網(wǎng)絡進行數(shù)據(jù)傳輸
2.創(chuàng)建的軟件架構有哪些雏门?
CS/BS
3.CS/BS的優(yōu)缺點
CS:客戶端服務端模式需要開發(fā)客戶端
BS:瀏覽器服務端模式不需要開發(fā)客戶端
CS:適合定制專業(yè)化的辦公軟件和網(wǎng)游
BS:適合移動物聯(lián)網(wǎng)應用既绕,可以在任何地方隨時訪問的系統(tǒng)
二.網(wǎng)絡編程三要素
IP:設備在網(wǎng)絡上的地址碑韵,是唯一標識符狈谊。
端口號:應用程序在設備中唯一的標識
協(xié)議:數(shù)據(jù)在網(wǎng)絡上傳輸?shù)囊?guī)則,常見的協(xié)議有UDP,TCP,http剥懒,https,ftp
1.1IP
ipv4(internet protocol version4)采用32位地址長度合敦,分成4組初橘,轉(zhuǎn)換方式:點分十進制,目前主流方式充岛,但是已經(jīng)用完了
目前解決方法:利用局域網(wǎng)ip解決ip不夠用的問題
特殊ip地址127.0.0.1保檐,本機ip,永遠只會尋找當前所在本機
常用cmd命令
inconfig:查看本機ip地址
ping:檢查網(wǎng)絡(局域網(wǎng)也可以檢查外網(wǎng))是否連通
ipv6:采用128位地址長度崔梗,分成8組一組16位,轉(zhuǎn)換方式:冒分十六進制,為了解決ipv4不夠用才出現(xiàn)的
1.2java中用來表示ip的類
InetAddress:給定主機的名稱犬绒,根據(jù)系統(tǒng)上配置的名稱服務返回其IP地址數(shù)組。
package com.wyx.ip;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo1 {
public static void main(String[] args) throws UnknownHostException {
//InetAddress.getByName(string host)確定主機名稱的ip地址场躯,主機名稱可以是機器名稱,也可以是ip地址,返回此對象
// InetAddress inetAddress = InetAddress.getByName("192.168.0.103");
InetAddress inetAddress = InetAddress.getByName("LAPTOP-4R43I4O8");
//打印這個對象
System.out.println(inetAddress);//LAPTOP-4R43I4O8/192.168.0.103
//調(diào)用下面的方法
System.out.println(inetAddress.getHostAddress());//192.168.0.103
System.out.println(inetAddress.getHostName());//LAPTOP-4R43I4O8
}
}
2.1端口號
端口號:由兩個字節(jié)表示的整數(shù)旅挤,取值范圍:0~65535
其中0~1023之間端口號用于一些知名的網(wǎng)絡服務或者應用
一個端口號只能被一個應用程序使用
3.1協(xié)議
UDP協(xié)議
用戶數(shù)據(jù)報協(xié)議
UDP是面向無連接的通信協(xié)議(不管是否鏈接成功踢关,都要發(fā)送消息)
速度快,有大小限制最多發(fā)送64k粘茄,數(shù)據(jù)不安全签舞,易丟失數(shù)據(jù)
發(fā)送端
package com.wyx.udp;
import java.io.IOException;
import java.net.*;
public class SendMessageDemo {
public static void main(String[] args) throws IOException {
//發(fā)送數(shù)據(jù)
//1.創(chuàng)建DatagramSocket()對象
//參數(shù):空參所有端口號中隨機一個進行使用
//有參:從指定的端口號中發(fā)送
DatagramSocket datagramSocket = new DatagramSocket();
//2.打包數(shù)據(jù)
String str="你好";//需要發(fā)送的數(shù)據(jù)
byte[] bytes = str.getBytes();//把需要發(fā)送的數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組
//創(chuàng)建InetAddress對象,用于指定接收方的ip地址
InetAddress byName = InetAddress.getByName("127.0.0.1");//發(fā)送給指定電腦
int port = 10086;//接收端的端口號
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, port);//打包數(shù)據(jù)
//3.發(fā)送數(shù)據(jù)
datagramSocket.send(datagramPacket);
//4.釋放資源
datagramSocket.close();
}
}
接收端
package com.wyx.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
//接受數(shù)據(jù)
//1.創(chuàng)建DatagramSocket對象
//在創(chuàng)建接受數(shù)據(jù)對象時候柒瓣,一定要綁定接口儒搭,并且與發(fā)送端 發(fā)送的的接口一致
DatagramSocket datagramSocket = new DatagramSocket(10086);
//2.接受數(shù)據(jù)(接收到的數(shù)據(jù)是一個數(shù)據(jù)包)
byte[] bytes = new byte[1024];//用來存放數(shù)據(jù)
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);//創(chuàng)建一個數(shù)據(jù)包,用來存放接收到的數(shù)據(jù)包
//receive該方法是阻塞的嘹朗,程序執(zhí)行到這一步的時候师妙,會在這里死等,等發(fā)送端發(fā)送消息
datagramSocket.receive(datagramPacket);//接受數(shù)據(jù)屹培,把接收到的數(shù)據(jù)放到datagramPacket包中
//3.解析數(shù)據(jù)包
byte[] data = datagramPacket.getData();//獲取數(shù)據(jù)默穴,獲取到的數(shù)據(jù)就是上面bytes變量中存的數(shù)據(jù)
int length = datagramPacket.getLength();//獲取數(shù)據(jù)的字節(jié)數(shù)
InetAddress address = datagramPacket.getAddress();//獲取發(fā)送方的ip地址
int port = datagramPacket.getPort();//獲取發(fā)送方的端口
System.out.println("接受數(shù)據(jù):" + new String(data,0,length));//接受數(shù)據(jù):你好
System.out.println("發(fā)送方的ip地址是:" + address);//發(fā)送方的ip地址是:/127.0.0.1
System.out.println("發(fā)送方端口號是:" + port);//發(fā)送方端口號是:50574
//4.釋放資源
datagramSocket.close();
}
}
先運行接收端,再運行發(fā)送端
練習
UDP發(fā)送數(shù)據(jù):數(shù)據(jù)來源于鍵盤錄入褪秀,直到輸入的數(shù)據(jù)是886蓄诽,發(fā)送數(shù)據(jù)結束
UDP接受數(shù)據(jù):因為接收端不知道發(fā)送端什么時候停止發(fā)送,故采用死循環(huán)的方式接受
發(fā)送端
package com.wyx.udp2;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class SendMessageDemo {
public static void main(String[] args) throws IOException {
//1創(chuàng)建對象
DatagramSocket datagramSocket = new DatagramSocket();
//2打包數(shù)據(jù)
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("請輸入你要發(fā)送的數(shù)據(jù)");
String next = scanner.next();
if (next.equals("886")) {
break;
} else {
byte[] bytes = next.getBytes();
InetAddress byName = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, port);
//3發(fā)送數(shù)據(jù)
datagramSocket.send(datagramPacket);
}
}
//4.釋放資源
datagramSocket.close();
}
}
接收端
package com.wyx.udp2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
//1創(chuàng)建對象
DatagramSocket datagramSocket = new DatagramSocket(10086);
//2接受數(shù)據(jù)
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
while (true) {
datagramSocket.receive(datagramPacket);
//3解析數(shù)據(jù)
System.out.println("接受數(shù)據(jù):" + new String(datagramPacket.getData(),0,datagramPacket.getLength()) );
}
//4.釋放資源
// datagramSocket.close();
}
}
UDP的三種通信方式
1.單播(一對一發(fā)送數(shù)據(jù))
2.組播(一對一組發(fā)送數(shù)據(jù))
3.廣播(一對局域網(wǎng)中全部發(fā)送數(shù)據(jù))
TCP協(xié)議
傳輸控制協(xié)議
TCP協(xié)議是面向鏈接的通訊協(xié)議媒吗。(先判斷是否鏈接成功仑氛,鏈接成功之后,再去發(fā)送消息)
速度慢闸英,沒有大小限制锯岖,數(shù)據(jù)安全
TCP通信協(xié)議是一種可靠的網(wǎng)絡協(xié)議,它在通信的兩端各建立一個Socket對象
通信之前要保證鏈接已經(jīng)建立
通過Socket產(chǎn)生IO流來進行網(wǎng)絡通信
客戶端發(fā)送數(shù)據(jù)
package com.wyx.tcp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
//客戶端甫何,發(fā)送數(shù)據(jù)出吹,tcp協(xié)議
public class Client {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建Socket對象
//細節(jié):在創(chuàng)建對象同時會連接服務器
//如果連接不上,會報錯
Socket socket = new Socket("127.0.0.1", 10000);
//2.可以從連接通道中獲取輸出流
OutputStream os = socket.getOutputStream();
os.write("你好呀".getBytes());//需要發(fā)送的數(shù)據(jù)
//3.釋放資源
os.close();
socket.close();
}
}
服務端接受數(shù)據(jù)
package com.wyx.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
//服務端辙喂,接受數(shù)據(jù)捶牢,tcp協(xié)議
public class Server {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建ServerSocket對象,端口號要和發(fā)送方端口號一致
ServerSocket ss = new ServerSocket(10000);
//2.監(jiān)聽客戶端鏈接巍耗,就是調(diào)用accept方法秋麸,死等,等客戶端來鏈接炬太,鏈接成功會返回客戶端的鏈接對象
Socket socket = ss.accept();
//3.從鏈接通道中獲取輸入流讀取數(shù)據(jù)
InputStream is = socket.getInputStream();//字節(jié)輸入流
InputStreamReader isr = new InputStreamReader(is);//將字節(jié)流轉(zhuǎn)為字符流
int b;
while ((b=isr.read())!=-1){
System.out.println((char)b);
}
//4.釋放資源
socket.close();//斷開與客戶端鏈接
ss.close();//關閉服務器
}
}