1. 程式人生 > >《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第3節 USB-4G移植(移遠AG35開發-GPS解析及程式設計)

《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第3節 USB-4G移植(移遠AG35開發-GPS解析及程式設計)

檢視參考手冊,移遠帶有GPS的晶片的USB Serial如下。
這裡寫圖片描述

2.1應用簡介

1、若不使用 AT+QGPSCFG 指令對AG35進行配置,則會以預設引數開啟GPS引數,NMEA埠開始上報,"gpsnmeatype"預設值為31,上報間隔為1s,每次上報所有種類的NMEA資料(GGA\RMC\GSV\GSA\VTG),若採用此預設配置,大多數使用者會覺得單次上報的資料太多且很多資訊重複,建議大家使用QGPSCFG配置自己需要的NMEA資料格式,具體格式的差異可參考網上對NMEA資料的說明。
2、Linux環境下對NMEA資料的獲取:
cat /dev/ttyUSB1 & // NMEA資料從ttyUSB1輸出
echo “AT+QGPS=1” > /dev/ttyUSB2 // 開啟GPS會話
可觀察到ttyUSB1輸出NMEA資料,如下:
這裡寫圖片描述


3、程式設計過程中,若有固定頻率更新位置需求,可考慮採用讀取NMEA埠資料的形式,並將其配置適合自己需求的NMEA格式和資料更新間隔。若產品執行獲取位置指令的頻率較低且間隔時間不固定,也可考慮直接在AT指令埠使用AT+QGPSLOC指令進行實時位置資訊的獲取。

2.2 GPS資料解析

NMEA 0183是美國國家海洋電子協會(National Marine Electronics Association )為海用電子裝置制定的標準格式。目前業已成了GPS導航裝置統一的RTCM(Radio Technical Commission for Maritime services)標準協議。
GPS接收機上電後,會自動通過串列埠或USB口傳送NMEA0183格式的資料包,它是一組包含有各種地理位置資訊的字串,字串格式為:
$資訊型別,xxx,xxx,xxx,xxx,xxx,xxx,xxx,
每行開頭的字元都是‘$’,接著是資訊型別,後面是資料,以逗號分隔開。一行完整的資料如下:
$GPRMC,063102.00,A,2932.293196,N,10636.147385,E,0.0,45.5,250818,2.3,W,A*10

資訊型別為:
GPVTG:地面速度資訊
GPRMC:推薦最小定位資訊
GPGSA:當前衛星資訊
GPGGA:GPS定位資訊
GPGSV:可見衛星資訊
這裡我們只解析GPRMC和GPGGA的資訊。

 GPRMC資料詳解:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
< 1> UTC時間,hhmmss(時分秒)格式
< 2> 定位狀態,A=有效定位,V=無效定位
< 3> 緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)
< 4> 緯度半球N(北半球)或S(南半球)
< 5> 經度dddmm.mmmm(度分)格式(前面的0也將被傳輸)
< 6> 經度半球E(東經)或W(西經)
< 7> 地面速率(000.0~999.9節,前面的0也將被傳輸)
< 8> 地面航向(000.0~359.9度,以真北為參考基準,前面的0也將被傳輸)
< 9> UTC日期,ddmmyy(日月年)格式
< 10> 磁偏角(000.0~180.0度,前面的0也將被傳輸)
< 11> 磁偏角方向,E(東)或W(西)
< 12> 模式指示(僅NMEA0183 3.00版本輸出,A=自主定位,D=差分,E=估算,N=資料無效)

解析內容:
1.時間,這個是格林威治時間,是世界時間(UTC),我們需要把它轉換成北京時間(BTC),BTC和UTC差了8個小時,要在這個時間基礎上加8個小時。
2.定位狀態,在接收到有效資料前,這個位是‘V’,後面的資料都為空,接到有效資料後,這個位是‘A’,後面才開始有資料。
3.緯度,我們需要把它轉換成度分秒的格式,計算方法:
如接收到的緯度是:4546.40891
4546.40891 / 100 = 45.4640891 可以直接讀出45度
4546.40891–45 * 100 = 46.40891 可以直接讀出46分
46.40891–46 = 0.40891 * 60 = 24.5346 讀出24秒
所以緯度是:45度46分24秒。

4.南北緯,這個位有兩種值‘N’(北緯)和‘S’(南緯)
5.經度的計算方法和緯度的計算方法一樣
6.東西經,這個位有兩種值‘E’(東經)和‘W’(西經)
7.速率,這個速率值是 海里/時,單位是節,要把它轉換成千米/時,根據:1海里 = 1.85公里,把得到的速率乘以1.85。
8.航向,指的是偏離正北的角度
9.日期,這個日期是準確的,如:200818表示2018年08月20日,這個日期是準確的,不需要轉換。

 GPGGA資料詳解
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx
$GPGGA:起始引導符及語句格式說明(本句為GPS定位資料);
<1> UTC時間,格式為hhmmss.sss;
<2> 緯度,格式為ddmm.mmmm(第一位是零也將傳送);
<3> 緯度半球,N或S(北緯或南緯)
<4> 經度,格式為dddmm.mmmm(第一位零也將傳送);
<5> 經度半球,E或W(東經或西經)
<6> 定位質量指示,0=定位無效,1=定位有效;
<7> 使用衛星數量,從00到12(第一個零也將傳送)
<8> 水平精確度,0.5到99.9
<9> 天線離海平面的高度,-9999.9到9999.9米 M 指單位米
<10> 大地水準面高度,-9999.9到9999.9米 M 指單位米
<11> 差分GPS資料期限(RTCM SC-104),最後設立RTCM傳送的秒數量
<12> 差分參考基站標號,從0000到1023(首位0也將傳送)。

2.3 GPS程式設計

GPS解析主要有兩個部分,一個是USB轉串列埠的配置,另外一個就是GPS的解析。下面就一一介紹。
1.串列埠配置
由於我是通過串列埠來進行資料傳輸,也就是把GPS定位的資訊,通過串列埠最後輸出到我們的終端裝置上。
【uart_GPS_config.c】

/**
  ******************************************************************************
  * @file    uart_GPS_config.c
  * @author  Bruceou
  * @version V1.0
  * @date    2018.04.11
  * @brief   串列埠設定
  ******************************************************************************
  */
/**Includes*********************************************************************/
#include "uart_GPS_config.h"
 
/**
  * @brief     串列埠設定函式
  * @param     fd
               baud_rate
			   data_bits
			   parity
			   stop_bits
  * @retval    int
  */
 int set_GPS_com_config(int fd,int baud_rate,int data_bits, char parity, int stop_bits)	
{
	struct termios new_cfg;
	int speed;
							    
	/* 儲存並測試現有串列埠引數設定,在這裡如果串列埠號等出錯,會有相關的出錯資訊 */
	
	if (tcgetattr(fd, &new_cfg) != 0) 
	{
		perror("tcgetattr save");	
		return -1;
	}

	//修改控制模式,保證程式不會佔用串列埠  
	new_cfg.c_cflag |= CLOCAL;  
	//修改控制模式,使得能夠從串列埠中讀取輸入資料  
	new_cfg.c_cflag |= CREAD;  
	new_cfg.c_oflag &= ~(ONLCR | OCRNL);
	new_cfg.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
	new_cfg.c_iflag &= ~(ICRNL | INLCR);
	new_cfg.c_iflag &= ~(IXON | IXOFF | IXANY);
	
	/* 設定波特率 */
	switch (baud_rate)
	{
		case 2400:	
		{
			speed = B2400;	
		}
		break;		
		case 4800:
		{
			speed = B4800;
		}
		break;
		case 9600:
		{
			speed = B9600;
		}
		break;
		case 19200:
		{
			speed = B19200;
		}
		break;
		case 38400:	
		{
			speed = B38400;
		}
		break;
		default:			
		case 115200:		
		{
			speed = B115200;			
		}		
		break;		
	}
	
	cfsetispeed(&new_cfg, speed);//輸入波特率	
	cfsetospeed(&new_cfg, speed);//輸出波特率
	switch (data_bits) /* 設定資料位 */	
	{		
		case 7:
		{
			new_cfg.c_cflag |= CS7;		
		}		
		break;	
		default:	
		case 8:
		{
			new_cfg.c_cflag |= CS8;
		}		
		break;		
	}
	
	switch (parity) /* 設定奇偶校驗位 */	
	{
		default:	
		case 'n':	
		case 'N':	
		{
			new_cfg.c_cflag &= ~PARENB; 
			new_cfg.c_iflag &= ~INPCK; 	
		}	
		break;	
		case 'o':
		case 'O':
		{
			new_cfg.c_cflag |= (PARODD | PARENB); 
			new_cfg.c_iflag |= INPCK; 
		}	
		break;		
		case 'e':
		case 'E':
		{
			new_cfg.c_cflag |= PARENB; 
			new_cfg.c_cflag &= ~PARODD; 
			new_cfg.c_iflag |= INPCK; 
				
		}	
		break;			
		case 's': /* as no parity */		
		case 'S':
		{
			new_cfg.c_cflag &= ~PARENB;
			new_cfg.c_cflag &= ~CSTOPB;
		}	
		break;	
	}
	switch (stop_bits) /* 設定停止位 */	
	{
		default:
		case 1:
		{
			new_cfg.c_cflag &= ~CSTOPB;		
		}	
		break;	
		case 2:
		{
			new_cfg.c_cflag |= CSTOPB;		
		}
	}
	//修改輸出模式,原始資料輸出  
	new_cfg.c_oflag &= ~OPOST;  
	new_cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//我加的  
	new_cfg.c_lflag &= ~(ISIG | ICANON);  

	//設定等待時間和最小接收字元  
	new_cfg.c_cc[VTIME] = 0; /* 讀取一個字元等待0*(0/10)s */    
	new_cfg.c_cc[VMIN] = 1; /* 讀取字元的最少個數為0 */  

	//如果發生資料溢位,接收資料,但是不再讀取 重新整理收到的資料但是不讀
	tcflush(fd, TCIFLUSH); /* 處理未接收字元 */	
	if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0) /* 啟用新配置 */	
	{
		perror("tcsetattr action");
		return -1;	
	} 
	//printf("serial set success\n");
	return 0;	
}

/**
  * @brief     開啟串列埠函式
  * @param     com
  * @retval    int
  */
int open_GPS_port(const char *com_port)
{
	int fd;

	/*分別為com1,com2, com3對應 ttyS0 ttyS1 ttyS2 */			    
	fd = open( com_port, O_RDWR|O_NOCTTY|O_NDELAY);  		 
	if (fd < 0)  
	{
		perror("Can't Open Serial Port");  
		return -1;										     
	}
	/*恢復串列埠為阻塞狀態*/
	if (fcntl(fd,F_SETFL,0)<0)
	{
		perror("fcntl F_SETFL\n");
	}
	/*測試是否為終端裝置*/
	if(isatty(STDIN_FILENO) == 0)
	{
		perror("standard input is not a terminal device");
	}
	return fd;
}

/**
  * @brief     串列埠初始化函式
  * @param     com_port
  * @retval    int
  */
int init_GPS_port(const char *com_port)
{
	int fd;

	if ((fd = open_GPS_port(com_port)) < 0 )
	{
		perror("open_port");
		return -1;
	}
	
	if(set_GPS_com_config(fd,9600,8,'N',1) < 0)
	{
		perror("set_com_config");
		return -1;
	}
	return fd;
}


【uart_GPS_config.h】

#ifndef _UART_GPS_CONFIG_H_
#define _UART_GPS_CONFIG_H_
 
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>

#define BUFFER_SIZE  36

#define DEVICE_AT_GPS        "/dev/ttyUSB2"
#define DEVICE_DATA_GPS      "/dev/ttyUSB1"

int set_GPS_com_config(int fd,int baud_rate, int data_bits,char parity,int stop_bits);
int open_GPS_port(const char *com_port);
int init_GPS_port(const char *com_port);

#endif

2.GPS資料分析
【GPS.c】

/**
  ******************************************************************************
  * @file    GPS.c
  * @author  Bruceou
  * @version V1.0
  * @date    2018.08.11
  * @brief   GPS 解析
  ******************************************************************************
  */
/**Includes*********************************************************************/
#include "GPS.h"

char *buff = NULL;

GPRMC_t gprmc;
GPGGA_t gpgga;
	
/**
  * @brief     GPS解析函式
  * @param     AT_fd:串列埠檔案描述符
  * @          DATA_fd:串列埠檔案描述符
  * @retval    Nono
  */
void GPS_Analysis(int AT_fd,int DATA_fd)
{
	int  nread,nwrite;
	char send_buff[16];
    char recv_buff[512];
	char *ptr = NULL;
	char AT_Buff[16];
	int ret = 0;
#if 0
	uint32_t time  =0;
	uint32_t lat   =0 ;
	uint32_t lon   =0;
	uint32_t speed =0;
	uint32_t head  =0;
	uint32_t alt   =0;
#endif
	
	while(1)
	{
		memset(AT_Buff,0,sizeof(AT_Buff));
		strcpy(AT_Buff, "AT+QGPS=1");
		GPS_Set(AT_fd , AT_Buff);
		
		if(buff != NULL)
		{
			break;
		}
		
		memset(AT_Buff,0,sizeof(AT_Buff));
		strcpy(AT_Buff, "AT+QGPSEND");
		GPS_Set(AT_fd , AT_Buff);
		sleep(1);
	}
	
	//接收資料
	while(1)
	{
		memset(&gprmc, 0, sizeof(gprmc));
		memset(&gpgga, 0, sizeof(gpgga));
		memset(recv_buff,0,sizeof(recv_buff));
		nread = read(DATA_fd,recv_buff,sizeof(recv_buff));

#ifdef DEBUG_GPS	
		printf("nread=%d,%s\n",nread,recv_buff);
		printf("=================2===================\n");
#endif
		//strcpy(buff, recv_buff);
		//儲存資料
		ptr = strstr(recv_buff, "$GPRMC");
		ret = sscanf(ptr, "$GPRMC,%f,%c,%f,%*c,%f,%*c,%f,%f,%d,%f,%*c,%*c*", 
		                          &gprmc.time,&gprmc.state, &gprmc.lat, &gprmc.lon,
						          &gprmc.speed, &gprmc.head, &gprmc.date,&gprmc.dec);
		
		ptr = strstr(recv_buff, "$GPGGA");
		ret = sscanf(ptr, "$GPGGA,%f,%f,N,%f,E,%d,%d,%f,%f,M,%f,M,,*", 
					              &gpgga.time, &gpgga.lat, &gpgga.lon,
		                          &gpgga.state, &gpgga.num, &gpgga.hdop, &gpgga.alt, &gpgga.geoid);
#if 0		
		time = (int)(gprmc.time*100) % 100   + ((int)gprmc.time % 100) * 100 +\
			   ((int)gprmc.time%10000/100) *60 * 100 + ((int)gprmc.time/10000)* 3600 * 100;
		
		lat 	=  ((int)(gprmc.lat/100) + (gprmc.lat-(int)gprmc.lat/100*100)/60)*10000000;
		lon 	= ((int)(gprmc.lon/100) + (gprmc.lon-(int)gprmc.lon/100*100)/60)*10000000;
		speed   = gprmc.speed* 1.852;
		head    = gprmc.head;
		
		alt     = gpgga.alt;
#endif	
		//列印資料
		print_GPS_RMC(&gprmc);
		print_GPS_GGA(&gpgga);			
	}
}

/**
  * @brief     GPS開啟函式
  * @param     AT_fd:串列埠檔案描述符
  * @          AT :AT指令
  * @retval    Nono
  */
void GPS_Set(int AT_fd,char *AT)
{
	int  nread,nwrite;
	char send_buff[16];
    char recv_buff[64];
	
	memset(send_buff,0,sizeof(send_buff));
    strcpy(send_buff, AT);
    strcat(send_buff,"\r");
    nwrite = write(AT_fd,send_buff,strlen(send_buff));

#ifdef DEBUG_GPS
	printf("nwrite=%d,%s\n",nwrite,send_buff);
#endif
	//waiting for AT's ACK等待迴應
	memset(recv_buff,0,sizeof(recv_buff));
    nread = read(AT_fd,recv_buff,sizeof(recv_buff));
	
	buff = strstr(recv_buff,"OK");
	//memset(buff,0,strlen(buff));
	
#ifdef DEBUG_GPS	
	printf("nread=%d,%s\n",nread,recv_buff);
	printf("================1======================\n");
#endif

}

/**
  * @brief     GPS-RMC資訊列印
  * @param     gprmc_data:
  * @retval    Nono
  */
void print_GPS_RMC(GPRMC_t *gprmc_data)
{
	printf("                                                           \n");
    printf("===========================================================\n");
    printf("==              全球GPS定位導航模組                      ==\n");
    printf("==              Author:BruceOu                          ==\n");
    printf("==              Email:[email protected]                   ==\n");
    printf("================RMC資訊====================================\n");
    printf("===========================================================\n");
    printf("==   GPS state bit : %c  [A:有效狀態 V:無效狀態]           \n",gprmc_data->state);
    printf("==   Date : 20%02d-%02d-%02d                               \n",gprmc_data->date%100,(gprmc_data->date%10000)/100,gprmc_data->date/10000);
    printf("==   緯度 : 北緯:%d度%d分%d秒                              \n",((int)gprmc_data->lat) / 100, (int)(gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100)), (int)(((gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100)) - ((int)gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100))) * 60.0));
    printf("==   經度 : 東經:%d度%d分%d秒                              \n",((int)gprmc_data->lon) / 100, (int)(gprmc_data->lon - ((int)gprmc_data->lon / 100 * 100
            
           

相關推薦

Linux作業系統-系統移植8 USB-4G/LTE移植 -3 USB-4G移植AG35開發-GPS解析程式設計

檢視參考手冊,移遠帶有GPS的晶片的USB Serial如下。 2.1應用簡介 1、若不使用 AT+QGPSCFG 指令對AG35進行配置,則會以預設引數開啟GPS引數,NMEA埠開始上報,"gpsnmeatype"預設值為31,上報間隔為1s,每次上報所有種

Linux作業系統-系統移植8 USB-4G/LTE移植 -4 USB-4G移植EC20開發-Gobi撥號

開發環境 主機:ubuntu12.04 開發板核心版本:linux-2.6.35 【注】EC20支援PPP撥號,Gobi撥號和QMI撥號,筆者使用的是Gobi撥號,關於另外兩種撥號請參考官方文件,後文的附件連結中已經給出了參考文件。 3.1 USB Serial

Linux作業系統-系統移植8 USB-4G/LTE移植 -2 USB-4G移植中興ME3760移植

ME3760 是一款Mini PCI-E介面的LTE 模組,支援LTE TDD band38(2.6GHz),band39(1.9GHz),band40(2.3GHz); LTE FDD band7(2.6GHz),向下相容TD-SCDMA A頻段(2.1GHz

Linux作業系統-系統移植8 USB-4G/LTE移植 -1 USB-4G移植C華為E392u­924G移植

1.3 PPP編譯 1.獲取原始碼 PPP官網下載:https://download.samba.org/pub/ppp/ 下載解壓ppp-2.4.7.tar.gz原始碼,存放在/home/farsig

Linux作業系統-系統移植8 USB-4G/LTE移植 -1 USB-4G移植 F華為E392u­924G移植

1.6啟動撥號指令碼 $mkdir shell_script $cd /shell_script $ vi usb.sh 輸入以下內容,然後儲存退出。 usb_modeswitch -W -c /etc

Linux作業系統-系統移植7 工具移植 -3 Mini-xml移植

開發環境: 主機環境:Ubuntu 12.04 目標機環境:Exynos4412開發板(Linux 3.0.5) 一個輕量級的xml庫,可完成讀寫。適合系統資源受限的嵌入式裝置。 原始碼下載:https

Linux作業系統-系統移植7 工具移植 -2 SSH服務移植

開發環境: 主機:Ubuntu12.04 開發板:Exynos4412 2.1編譯相關檔案 SSH協議族可以用來進行遠端控制, 附加的SFTP協議可輕鬆實現在計算機之間傳送檔案。而實現此功能的傳統方式,如telnet(終端模擬協議)、 rcp ftp、 rlog

Linux命令應用大詞典-8 日期和時間

硬件時鐘 顯示 linu 時鐘 主機 style hwclock 硬件 暫停 8.1 cal:顯示日歷信息 8.2 date:顯示和設置系統日期和時間 8.3 hwclock:查看和設置硬件時鐘 8.4 clock:查看和設置硬件時鐘 8.5 clockdiff:主機之間

Linux學習筆記】8 Linux shell基礎知識

linux centos shell 通配 8.1shell介紹shell是一個命令解釋器,提供人機交互。支持特定語法。每個用戶都可以有自己特定的shell(bash)。CentOS7默認bash(Bourne Agin Shell)。其他還有zsh、ksh等。 8.2命令歷史命令歷史存放於

易學筆記-Linux命令-8:從shell眼中看世界

第8章:從shell眼中看世界/8.0 echo:單詞分割機制 echo:單詞分割機制 格式:echo  結果集,這裡的結果集可能是 某個字串:abc 多個字串:abc  edf 命令結果: ls  

連結裝載與庫 8 linux共享庫的組織

由於動態連結的優點,大量的程式使用動態連結機制,導致系統裡面存在數量極為龐大的共享物件。必須得有很好的機制來管理這些共享庫,否則這些共享物件散落在各個目錄下,長期的維護,升級,都有會很大的問題。 8.1 共享庫版本 8.1.1 共享庫的相容性 共享庫的版本會不斷的更新,以修正原有

linux核心設計與實現 —— 中斷和中斷處理78

中斷和中斷處理 中斷的目的:讓處理器最快地響應外部硬體的請求。 中斷本質上是一種特殊的電訊號,由硬體裝置發向處理器,處理器反映到作業系統中,最後由作業系統處理這個中斷電訊號。 不同的裝置對應的中斷不同。每個中斷都通過一個唯一的數字標記,這個標記通常被稱為中

82講特殊函數介紹

turn 函數介紹 spl .cn scan margin urn printf return #include"stdio.h" int fact(int n) //求階乘函數 { int f=1,i; fo

8:Shell腳本歸檔與壓縮

extract config 生成 -- dir exclude 硬盤分區 txt name 第8章:Shell腳本歸檔與壓縮   定期備份不可小視,我們可以通過shell腳本來實現備份自動化。其中數據備份一般要使用到歸檔與壓縮,歸檔與壓縮對於系統

82《MonkeyRunner源代碼剖析》MonkeyRunner啟動執行過程-解析處理命令行參數

path 轉載 iss 命令 code rst pri bsp ack MonkeyRunnerStarter是MonkeyRunner啟動時的入口類,由於它裏面包括了main方法.它的整個啟動過程主要做了以下幾件事情:解析用戶啟動MonkeyRunner時從命令行傳輸

8 包管理

重新 裝包 自己的 align love ocs 重定向 客戶端程序 target 本文目錄: 8.1 Linux上構建C程序的過程 8.2 包基礎知識 8.3 rpm管理包 8.4 yum管理包 8.5 補丁工具diff和patch 8.6 源碼編譯安裝程序 8.1

【C語言學習】《C Primer Plus》8 字符輸入/輸出和輸入確認

multipl 字符輸入 信號 first while 目的 bcd 問題 img 學習總結 1、緩沖區分為完全緩沖區(fully buffered)I/O和行緩沖區(line-buffered)I/O。對完全緩沖輸入來說,當緩沖區滿的時候會被清空(緩沖區內容發送至

Java編程思想讀書筆記_8

讀書筆記 div spl class alt oid ava 函數 opened 覆蓋私有方法 1 class Father { 2 private void f() { System.out.println("Father::f()"); } 3

8 傳輸層1_TCP/UDP協議的應用場景

一個數 選擇 str 根據 connect .cn eight 安全 器) 1. 傳輸層的兩個協議 1.1 TCP和UDP協議的應用場景 (1)TCP協議:如果要傳輸的內容比較多,需要將發送的內容分成多個數據包發送。這就要求在傳輸層用TCP協議,在發送方和接收方建立連接

8 傳輸層2_UDP協議

之前 用戶數 發送數據 1-1 效率 沒有 strong 而是 系統 2. 用戶數據報協議(UDP) 2.1 UDP的特點 (1)UDP是無連接的,即發送數據之前不需要建立連接,因此減少了開銷和發送數據之前的時延。 (2)UDP使用了盡最大努力交付,即不保證可靠交付,因此主