網絡編程:UDP TCP
1 網絡編程入門
1.1概述
網絡編程:在網絡通信協議下,不同計算機運行的程序,可以進行數據傳輸。
1.2三要素
IP地址:設備在網絡中的地址,是唯一的標識。
端口:應用程序在設備中唯一的標識。
協議:數據在網絡中傳輸的規則,常見的協議有UDP協議和TCP協議。
1.2.1 IP地址
IP:全稱“互聯網協議地址”,也稱IP地址。是分配給上網設備的數字標籤。常見的ip分類爲:ip4和ip6
ip4有四個字節,共有256x256x256x256=4,294,967,296種取值。然而ip地址的需求量越來越大,ip4模式下ip總數總是有限的,因此有了ip6.ip6採用128位地址長度,分成8組。
常用命令
ipconfig:查看本機ip地址
ping IP地址:檢查網絡是否連通
特殊ip地址:
127.0.0.1:是回送地址也稱本地迴環地址,可以表示本機的ip地址,一般用來測試使用
爲了方便我們對IP地址的獲取和操作,Java提供了一個類InetAddress供我們使用。
InetAddress address=InetAddress.getByName("DESKTOP-7EKUN48");//參數可以是主機名或者ip
System.out.println("獲取IP地址:"+address.getHostAddress());
System.out.println("獲取主機名:"+ address.getHostName());
1.2.2 端口
端口:應用程序在設備中唯一的標識。
端口號:用兩個字節表示的整數,它的取值範圍是0-65535.其中0-1023之間的端口用於一些知名的網絡服務或者應用。我們自己使用1024以上的端口號就可以了。
注意:一個端口號只能被一個應用程序使用。
1.2.3 協議
協議:計算機網絡中,連接和通信的規則被稱爲網絡通信協議
UDP協議:
用戶數據報協議(User Datagram Protocol)
UDP是面向無連接通信協議。
速度快,有大小限制一次最多發送64k,數據不安全,容易丟失數據。
TCP協議:
傳輸控制協議(Transmission Control Protocol)
TCP協議是面向連接的通信協議。
速度慢,沒有大小限制,數據安全。
2 UDP通信程序
2.1 UDP發送數據
1、創建發送端的DatagramSocket對象
2、創建數據,並把數據打包
3、調用DatagramSocket的方法發送數據
4、釋放資源
public class Client {
public static void main(String[] args) throws Exception{
//1、找碼頭
DatagramSocket ds=new DatagramSocket();
//2、打包禮物
/*
DatagramPacket(byte buf[], int length, InetAddress address, int port)
參數分別表示:打包的數據,數據長度,發送的Ip,端口
*/
String s="送給老丈人的禮物";
byte[] bytes=s.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
//3、把禮物給碼頭
ds.send(dp);
//4、付錢走羊
ds.close();
}
}
2.2 UDP接收數據
1、創建接收端的DatagramSocket對象
2、創建一個箱子,用於接收數據
3、調用DatagramSocket的方法接收數據並將數據放入箱子中
4、解析數據包,並把數據在控制檯顯示
5、釋放資源
/**
* UDP協議:面向無連接
* 1、先運行接收端,再運行發送端
* 2、如果接收端在啓動之後沒有接收到數據,那麼會死等(阻塞)
* 3、在接收數據的時候,需要調用getLength方法,表示接收到了多少字節
*/
public class Server {
public static void main(String[] args) throws Exception {
//1、找碼頭-------端口號表示是從哪個端口接收的(因爲客戶端將數據送到10000端口上了,所以要從該端口獲得)
DatagramSocket ds=new DatagramSocket(10000);
//2、拿新箱子
/*
DatagramPacket(byte buf[], int length)
接收到的數據 數據長度
*/
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
//3、新箱子裝禮物
ds.receive(dp);//如果接收不到數據,會在這一行阻塞
//4、老丈人從新箱子拿禮物
//打印string類型的接收內容 從0到接收的最後一個字符
System.out.println(new String(dp.getData(),0,dp.getLength()));
//5、拿完走羊
ds.close();
}
}
2.3 UDP通信程序練習(聊天室)
要求:
1、UDP發送數據:數據來自於鍵盤錄入,直到輸入的數據是886,發送數據結束。
2、UDP接收數據:因爲接收端不知道發送端什麼時候停止發送,故採用死循環接收。
public class Client {
public static void main(String[] args) throws IOException {
Scanner scanner=new Scanner(System.in);
while(true){
String data=scanner.nextLine();
if (data.equals("886")){
System.out.println("已停止傳送數據");
break;
}
byte[] bytes = data.getBytes();
DatagramSocket ds=new DatagramSocket();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
ds.send(dp);
ds.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10000);
while (true) {
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
}
//ds.close(); 不需要關閉 一直開啓
}
}
2.4 UDP三種通信方式
2.4.1 單播
以上UDP所有例子都是與一臺服務器進行通信。屬於單播。
2.4.2 組播
組播地址:224.0.0.0 ~ 239.255.255.255。其中224.0.0.0 ~ 224.0.0.255 爲預留的組播地址,我們使用224.0.1.0以上的地址即可。
public class Client {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
String data="hello 組播";
byte[] bytes = data.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("224.0.1.0"),10000);
ds.send(dp);
ds.close();
}
public class Server {
public static void main(String[] args) throws IOException {
MulticastSocket ms=new MulticastSocket(10000);
DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
//把當前計算機綁定組播地址,表示添加到這一組中
ms.joinGroup(InetAddress.getByName("224.0.1.0"));
ms.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
ms.close();
}
}
2.4.3 廣播
廣播地址:255.255.255.255
public class Client {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
String s="hello 廣播";
byte[] bytes = s.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("255.255.255.255"),10000);
ds.send(dp);
ds.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10000);
DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
ds.close();
}
}
3 TCP通信程序
3.1 TCP通信原理
TCP通信協議是一種可靠的網絡協議,它在通信的兩端各建立一個Socket對象。
通信之前要保證連接已經建立。
通過Socket產生IO流來進行網絡通信。
//TCP 發送端
public class Client {
public static void main(String[] args) throws Exception {
//1、創建一個socket對象
//Socket(String host, int port) 要連接的服務器ip,端口
Socket socket=new Socket("192.168.1.16",10000);
//2、獲取一個io流寫數據
OutputStream out=socket.getOutputStream();
out.write("hello tcp".getBytes());
//3、釋放資源
socket.close();
out.close();
}
}
//TCP 接收端
public class Server {
public static void main(String[] args) throws IOException {
//1、創建socket對象
ServerSocket ss=new ServerSocket(10000);
//2、等待客戶端連接
Socket accept=ss.accept();//等不到發送端就會阻塞
//3、獲取輸入流對象
InputStream in=accept.getInputStream();
int len=0;
while((len=in.read())!=-1){
System.out.print((char)len);
}
//4、釋放資源
in.close();
ss.close();
}
}
3.2 TCP通信程序練習
要求:
1、客戶端:發送數據,接收服務器反饋
2、服務器:接收數據,給出反饋
public class Client {
public static void main(String[] args) throws Exception{
Socket socket=new Socket("192.168.1.16",10000);
OutputStream os=socket.getOutputStream();
os.write("hello TCP".getBytes());
os.flush();
socket.shutdownOutput();//僅僅關閉輸出流,並寫一個輸出標記,對socket沒有影響
InputStream is = socket.getInputStream();
int len;
while((len=is.read())!=-1){
System.out.print((char)len);
}
is.close();
os.close();
socket.close();
}
}
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10000);
Socket accept=ss.accept();
InputStream is=accept.getInputStream();
int len=0;
while((len=is.read())!=-1){
System.out.print((char)len);
}
OutputStream os=accept.getOutputStream();
os.write("who are you?".getBytes());
os.flush();
os.close();
is.close();
accept.close();
ss.close();
}
}
3.3 TCP通信程序練習(文件上傳)
要求:
1、客戶端:將本地文件上傳到服務器。接收服務器的反饋。
2、服務器:接收客戶端上傳的文件,上傳完畢之後給出反饋。
public class Client {
public static void main(String[] args) throws Exception{
Socket socket=new Socket("192.168.1.16",10000);
//本地流 讀取本地文件
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("01_inetAddress/ClientDir/feder.jpg"));
//網絡流 寫到服務器
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
int len;
byte[] data=new byte[1024];
while((len=bis.read(data))!=-1){
bos.write(data,0,len);//通過網絡寫到服務器
}
//給服務器結束標記
socket.shutdownOutput();
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line="";
while((line=br.readLine())!=null){
System.out.println(line);
}
bis.close();
socket.close();
}
}
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10000);
Socket accept = ss.accept();
//網絡流 從客戶端讀取
BufferedInputStream bis=new BufferedInputStream(accept.getInputStream());
//本地流 寫到文件夾中
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("01_inetAddress/ServerDir/copy_feder.jpg"));
int len;
byte[] data=new byte[1024];
while((len=bis.read(data))!=-1){
bos.write(data,0,len);
}
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bw.write("上傳成功");
bw.newLine();
bw.flush();
bos.close();
accept.close();//socket關閉 網絡流一定關閉 不用手動bis.close()
ss.close();
}
}