IP地址,TCP/UDP通訊協議概述,Socket,UDP傳輸,多線程UDP聊天應用

IP地址,TCP/UDP通訊協議概述,Socket,UDP傳輸,多線程UDP聊天應用

一.JAVA網絡請求概述

關於JAVA的網絡請求,我們大致的可以分爲以下幾個分類

  • OSI
  • TCP/IP
  • 網絡通訊
  • IP地址
  • 端口號
  • 傳輸協議

拿這些都是幹嘛的呢?我們接下來都會講到

首先我們應該思考的是他們通信的一個過程的步驟

1.找到對方IP

2.數據發送到指定應用程序上,爲了識別,就有了端口的概念

3.定義通信協議(也就是後來的傳輸協議)國際協議/TCP/IP

4.三要素:IP,端口,協議

OK,那我們就研究下網絡模型,OSI和TCP/IP的區別
其實理解起來也不難,我們看一下他的邏輯結構就知道了

OSI

  • 應用層
  • 表示層
  • 會話層
  • 傳輸層
  • 網絡層
  • 數據鏈路層
  • 物理層

TCP/IP

  • 應用層
  • 傳輸層
  • 網絡層
  • 主機-網絡層

應用層,我們就在這裏玩,TCP封裝了就比較好用,他們都有使用規則,而我們常用的大概就是HTTP協議了

二.IP地址

通訊要素大致的就是這些,我們來說一下我們耳熟能詳的IP地址,他是什麼概念呢?
IP地址

網絡中設備的標識
可用主機名
本地迴環地址:127.0.0.1,主機名:location
端口號

用於標識進程的邏輯地址,不同進程的標識
有效端口:0-65535,其中0-1024系統使用或者保留,我們熟知的8080
通訊協議

通訊的規則
常見的TCP,UDP
我們可用用代碼獲得哦,先看API文檔,會發現JAVA給我們提供了一個類InetAddress

我們可用直接去用代碼使用

try {
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.toString());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

可以得到
這裏寫圖片描述

得到的本機的主機名和IP地址
當然,你要單獨獲取也是沒問題的

    try {
        InetAddress localHost = InetAddress.getLocalHost();
        String hostAddress = localHost.getHostAddress();
        String hostName = localHost.getHostName();
        System.out.println(localHost.toString());
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

三.TCP/UDP通訊協議概述

端口我們沒什麼可說的,我們直接說通訊協議,目前常見的就是TCP/UDP了,我們先來簡單的說下他們的概念

TCP

  • 建立連接,形成傳輸數據的通道
  • 在連接中進行大數據量傳輸
  • 通過三次握手完成連接,是可靠協議
  • 必須建立連接,效率稍微低點

UDP

  • 將數據及源和目的封裝在數據包中,不需要建立連接
  • 每個數據包的大小限制在64K內
  • 因無連接,是不可靠協議
  • 不需要建立連接,速度快
  • 這些這麼多,java肯定會給我們封裝對象的,這個是毋庸置疑的,那我們接着往下看

四.Socket

Socket就厲害了,我們先來看看他的概念
Socket就是爲網絡服務提供的一種機制
通信的兩端都有socket
網絡通信其實就是socket通信
數據在兩個socket通過IO傳輸
我們現在先說概念,後期再實戰

五.UDP傳輸

UDP傳輸的socket服務該怎麼建立?
DatagramSocket和DatagramPacket
建立發送端和接收端
建立數據包
調用socket的發送和接收方法
關閉socket
客戶端和服務端是兩個單獨的服務,我們可用來用代碼講解下,用到的就是DatagramSocket和DatagramPacket

所以這裏應該是有兩個,一個傳輸端,一個接收端

傳輸端

/**
 * 需求: 通過UDP傳輸方式將一段文字數據發送出去 
 * 思路: 
 * 1.建立UDP的socket服務 
 * 2.建立數據包 
 * 3.發送數據 
 * 4.關閉資源
 * 
 * @author LGL
 *
 */
public class UdpSend {
public static void main(String[] args) {
    try {
        // 1.建立UDP的socket服務,通過DatagramSocket對象
        DatagramSocket dSocket = new DatagramSocket();
        // 2.確定數據,封裝成數據包
        byte[] data = "udp".getBytes();
        DatagramPacket dp = new DatagramPacket(data, data.length,
                InetAddress.getByName("192.168.1.102"), 8080);
        // 3.發送數據
        dSocket.send(dp);
        // 4.關閉資源
        dSocket.close();
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

接收端

/**
 * 需求:接收指定端口發送過來的數據 
 * 思路: 
 * 1.定義socket服務
 * 2.定義數據包,存儲接收到的字節數據,因爲數據包對象中有更多功能可以提取字節數據中的不同數據信息
 * 3.通過socket的receive方法收到的數據存儲到數據包中 
 * 4.將這些不同的數據取出,打印 
 * 5.關閉資源
 * 
 * @author LGL
 *
 */
class UdpRece {
public static void main(String[] args) {
    try {
        // 1.創建服務,建立端點
        DatagramSocket dSocket = new DatagramSocket(8080);
        // 2.定義數據包,存儲數據
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);
        // 3.存儲
        dSocket.receive(dp);
        // 4.獲取其中的數據
        String ip = dp.getAddress().getHostAddress();
        String data = new String(dp.getData(), 0, dp.getLength());
        int port = dp.getPort();
        System.out.println(ip+":" + data + ":" + port);
        //5.關閉資源
        dSocket.close();
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

這樣就可以通信了

六.多線程UDP聊天應用

既然上面有模有樣的寫出來了,那我們可以動手寫一個應用了,我們繼續來看,我不開多個進程,我寫一個進程,兩個線程來實現聊天

/**
 * 編寫一個聊天應用程序 有收數據和發數據的部分,所以用到多線程的技術,一個接一個發 收和發的動作不一致,所以有兩個Runnable
 * 
 * @author LGL
 *
 */

public class UdpSpeak {
 public static void main(String[] args) {

    try {
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10000);

        new Thread(new send(sendSocket)).start();
        new Thread(new rece(receSocket)).start();

    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
  }
}

/**
 * 發送
 * 
 * @author LGL
 *
 */
class send implements Runnable {

private DatagramSocket socket;

public send(DatagramSocket socket) {
    this.socket = socket;
}

@Override
public void run() {
    try {
        BufferedReader bufr = new BufferedReader(new InputStreamReader(
                System.in));
        String line = null;
        while ((line = bufr.readLine()) != null) {
            if ("close".equals(line)) {
                break;
            }
            byte[] buf = line.getBytes();
            DatagramPacket dp = new DatagramPacket(buf, buf.length,
                    InetAddress.getByName("192.168.1.102"), 10000);
            socket.send(dp);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

/**
 * 接收
 * 
 * @author LGL
 *
 */
class rece implements Runnable {

private DatagramSocket socket;

public rece(DatagramSocket socket) {
    this.socket = socket;
}

@Override
public void run() {
    while (true) {
        try {
            byte[] buf = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);
            socket.receive(dp);

            String ip = dp.getAddress().getHostAddress();
            String data = new String(dp.getData(), 0, dp.getLength());
            int port = dp.getPort();
            System.out.println(ip + ":" + data + ":" + port);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

OK,搞定,其實主要還是要了解他的思想,編碼什麼的不重要的

好了,本篇主要是以UDP和概念爲起點,而且UDP用的較少,我們一般不是常接觸,真正要用的是TCP,所以會重點掌握,那本篇,我們先到這裏就好了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章