# JAVA之旅(三十二)——JAVA網絡請求,IP地址,TCP/UDP通訊協議概述,Socket,UDP傳輸,多線程UDP聊天應用
* * *
> GUI寫到一半電腦系統掛了,也就算了,最多GUI還有一個提示框和實例,我們暫時不講了,我們直接來重點吧,關于JAVA的網絡請求是怎么實現的?當然是HTTP協議,但是不可否認,他的概念和思想都是我們必須去涉及的,包括后面的tcp和socket等,好吧,我們開車吧!
## 一.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聊天應用
> 既然上面有模有樣的寫出來了,那我們可以動手寫一個應用了,我們繼續來看,我不開多個進程,我寫一個進程,兩個線程來實現聊天
~~~
package com.lgl.hellojava;
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;
/**
* 編寫一個聊天應用程序 有收數據和發數據的部分,所以用到多線程的技術,一個接一個發 收和發的動作不一致,所以有兩個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,所以會重點掌握,那本篇,我們先到這里就好了
版權聲明:本文為博主原創文章,博客地址:http://blog.csdn.net/qq_26787115,未經博主允許不得轉載。
- 0-發現
- AndroidInterview-Q-A
- Android能讓你少走彎路的干貨整理
- LearningNotes
- temp
- temp11
- 部分地址
- 0-待辦任務
- 待補充列表
- 0-未分類
- AndroidView事件分發與滑動沖突處理
- Spannable
- 事件分發機制詳解
- 1-Java
- 1-Java-01基礎
- 未歸檔
- 你應該知道的JDK知識
- 集合框架
- 1-Java-04合集
- Java之旅0
- Java之旅
- JAVA之旅01
- JAVA之旅02
- JAVA之旅03
- JAVA之旅04
- JAVA之旅05
- JAVA之旅06
- JAVA之旅07
- JAVA之旅08
- JAVA之旅09
- java之旅1
- JAVA之旅10
- JAVA之旅11
- JAVA之旅12
- JAVA之旅13
- JAVA之旅14
- JAVA之旅15
- JAVA之旅16
- JAVA之旅17
- JAVA之旅18
- JAVA之旅19
- java之旅2
- JAVA之旅20
- JAVA之旅21
- JAVA之旅22
- JAVA之旅23
- JAVA之旅24
- JAVA之旅25
- JAVA之旅26
- JAVA之旅27
- JAVA之旅28
- JAVA之旅29
- java之旅3
- JAVA之旅30
- JAVA之旅31
- JAVA之旅32
- JAVA之旅33
- JAVA之旅34
- JAVA之旅35
- 1-Java-05辨析
- HashMapArrayMap
- Java8新特性
- Java8接口默認方法
- 圖解HashMap(1)
- 圖解HashMap(2)
- 2-Android
- 2-Android-1-基礎
- View繪制流程
- 事件分發
- AndroidView的事件分發機制和滑動沖突解決
- 自定義View基礎
- 1-安卓自定義View基礎-坐標系
- 2-安卓自定義View基礎-角度弧度
- 3-安卓自定義View基礎-顏色
- 自定義View進階
- 1-安卓自定義View進階-分類和流程
- 10-安卓自定義View進階-Matrix詳解
- 11-安卓自定義View進階-MatrixCamera
- 12-安卓自定義View進階-事件分發機制原理
- 13-安卓自定義View進階-事件分發機制詳解
- 14-安卓自定義View進階-MotionEvent詳解
- 15-安卓自定義View進階-特殊形狀控件事件處理方案
- 16-安卓自定義View進階-多點觸控詳解
- 17-安卓自定義View進階-手勢檢測GestureDetector
- 2-安卓自定義View進階-繪制基本圖形
- 3-安卓自定義View進階-畫布操作
- 4-安卓自定義View進階-圖片文字
- 5-安卓自定義View進階-Path基本操作
- 6-安卓自定義View進階-貝塞爾曲線
- 7-安卓自定義View進階-Path完結篇偽
- 8-安卓自定義View進階-Path玩出花樣PathMeasure
- 9-安卓自定義View進階-Matrix原理
- 通用類介紹
- Application
- 2-Android-2-使用
- 2-Android-02控件
- ViewGroup
- ConstraintLayout
- CoordinatorLayout
- 2-Android-03三方使用
- Dagger2
- Dagger2圖文完全教程
- Dagger2最清晰的使用教程
- Dagger2讓你愛不釋手-終結篇
- Dagger2讓你愛不釋手-重點概念講解、融合篇
- dagger2讓你愛不釋手:基礎依賴注入框架篇
- 閱讀筆記
- Glide
- Google推薦的圖片加載庫Glide:最新版使用指南(含新特性)
- rxjava
- 這可能是最好的RxJava2.x入門教程完結版
- 這可能是最好的RxJava2.x入門教程(一)
- 這可能是最好的RxJava2.x入門教程(三)
- 這可能是最好的RxJava2.x入門教程(二)
- 這可能是最好的RxJava2.x入門教程(五)
- 這可能是最好的RxJava2.x入門教程(四)
- 2-Android-3-優化
- 優化概況
- 各種優化
- Android端秒開優化
- apk大小優化
- 內存分析
- 混淆
- 2-Android-4-工具
- adb命令
- 一鍵分析Android的BugReport
- 版本控制
- git
- git章節簡述
- 2-Android-5-源碼
- HandlerThread 源碼分析
- IntentService的使用和源碼分析
- 2-Android-9-辨析
- LRU算法
- 什么是Bitmap
- 常見圖片壓縮方式
- 3-Kotlin
- Kotlin使用筆記1-草稿
- Kotlin使用筆記2
- kotlin特性草稿
- Kotlin草稿-Delegation
- Kotlin草稿-Field
- Kotlin草稿-object
- 4-JavaScript
- 5-Python
- 6-Other
- Git
- Gradle
- Android中ProGuard配置和總結
- gradle使用筆記
- Nexus私服搭建
- 編譯提速最佳實踐
- 7-設計模式與架構
- 組件化
- 組件化探索(OKR)
- 1-參考列表
- 2-1-組件化概述
- 2-2-gradle配置
- 2-3-代碼編寫
- 2-4-常見問題
- 2-9-值得一讀
- 8-數據結構與算法
- 0臨時文件
- 漢諾塔
- 8-數據-1數據結構
- HashMap
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比較
- 遲到一年HashMap解讀
- 8-數據-2算法
- 1個就夠了
- Java常用排序算法(必須掌握的8大排序算法)
- 常用排序算法總結(性能+代碼)
- 必須知道的八大種排序算法(java實現)
- 9-職業
- 閱讀
- 書單
- 面試
- 面試-01-java
- Java面試題全集駱昊(上)
- Java面試題全集駱昊(下)
- Java面試題全集駱昊(中)
- 面試-02-android
- 40道Android面試題
- 面試-03-開源源碼
- Android圖片加載框架最全解析(二),從源碼的角度理解Glide的執行流程
- 面試-07-設計模式
- 面試-08-算法
- 面試-09-其他
- SUMMARY
- 版權說明
- temp111