TCP協(xié)議在STM32上的移植.doc_第1頁
TCP協(xié)議在STM32上的移植.doc_第2頁
TCP協(xié)議在STM32上的移植.doc_第3頁
TCP協(xié)議在STM32上的移植.doc_第4頁
TCP協(xié)議在STM32上的移植.doc_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、TCP 協(xié)議在STM32上的移植from2014-07-121.前言【由于 TCP 協(xié)議負載, 若有說的不對的地方,請及時指出,第一時間改正。本博文2013 年 2 月在某論壇發(fā)表,現(xiàn)搬遷至 CSDN 博客】從實用主義的角度出發(fā),學(xué)習嵌入式TCPIP 可以直接從本章節(jié)開始學(xué)習,甚至可以直接從HTTP 開始學(xué)習。我也曾經(jīng)是一個現(xiàn)實的實用主義者,以為有了AVRNET項目的源碼,修改移植之后便可以用于STM32。但是現(xiàn)實總是那么殘酷,對于一個還不熟悉HTML元素,沒有任何PHP和SOCKET編程知識的我來說,修改AVRNET的任何一行代碼都是不可能完成的任務(wù),我?guī)缀醪恢佬薷倪@行代碼造成哪些變化。但

2、是通過不斷地學(xué)習情況有所好轉(zhuǎn),這些學(xué)習包括 HTML , CSS, JaveScript, PHP, MySQL ,SOCKET 等。通過這些學(xué)習與積累慢慢地揭開了TCPIP 的面紗,而通過TCP 讓 STM32 返回 Hello 是多么令人興奮的事情。本文將通過分析和整理AVRNET 項目源碼并移植到STM32 平臺中,實現(xiàn) TCP 部分內(nèi)容,通過 TCP 打印 Hello 和 LED 控制實例說明 TCP 的使用方法。TCP 協(xié)議是是一個非常復(fù)雜的協(xié)議,本文并不會實現(xiàn)TCP 的方方面面,毫不避諱的說本文所用TCP 是不完整的TCP,沒有 TCP 堅持定時器和 TCP 重發(fā)功能,更別提滑動窗

3、口功能, TCP 的傳輸速度也低的可憐。本文試圖通過最簡單的代碼實現(xiàn)最基本的 TCP 功能,這些包括 TCP 建立,TCP數(shù)據(jù)包發(fā)送, TCP 關(guān)閉連接。【 STM32NET 學(xué)習筆記索引】【代碼倉庫】請以代碼倉庫中的內(nèi)容為主。1.2 相關(guān)資料【 ENC28J60 學(xué)習筆記】【 AVRNET 項目 (國外 ) 】【 AVR webserver 項目 (國外 ) 】 1.3 學(xué)習路線建議本文僅僅簡單的說明 TCP 使用的方法,通過一個 TCP發(fā)射的例子積累學(xué)習嵌入式網(wǎng)絡(luò)應(yīng)用的信心,但是這些知識是遠遠不夠的,你還需要學(xué)習以下知識。這些知識將幫助你設(shè)計和實現(xiàn)嵌入式網(wǎng)頁, 設(shè)計優(yōu)美的嵌入式web 類型

4、的 API 。【 HTML 】先學(xué)習 HTML4 ,再學(xué)習 HTML5【 CSS】先學(xué)習 CSS2,再學(xué)習 CSS3【 Javascript】【 JSON】強烈建議學(xué)習 JSON 格式和應(yīng)用方法?!?JQuery】建議先熟悉 Javascript,再學(xué)習 JQuery。【 PHP】和 PHP 工程師不同, 更多關(guān)注 HTTP 部分內(nèi)容?!緮?shù)據(jù)庫】 學(xué)習一款數(shù)據(jù)庫, 可以是 MySQL 或 SQLite ,熟悉基本操作增刪改查?!?Linux 】更多關(guān)注應(yīng)用層設(shè)計, 如果你不介意嘗試一下樹莓派吧?!綬ESTFul 】學(xué)習該框架,了解如何設(shè)計HTTP API 。【等等】知識真的是夠多的,請您保持耐

5、心。1.4 其他說明【 PC IP】01【 STM32 IP 】 5【 TCP 端口號】 30012.TCP 協(xié)議簡述本小節(jié)僅介紹TCP 如何建立連接, 發(fā)送數(shù)據(jù)和終止連接的技巧, 本文將不詳細講述TCP 首部中的各種字節(jié)含義,因為你可以找到很多說明的圖書。更多基礎(chǔ)內(nèi)容請參考?!?】 TCP IP 詳解卷 1 機械工程出版社出版【2】嵌入式Internet TCP IP 基礎(chǔ)、實現(xiàn)及應(yīng)用北京航空航天出版社2.1 TCP 的建立和終止在 STM32NET 項目中暫假定 PC 機為客戶端, STM32為服務(wù)器端。在這種情況下,有PC 機發(fā)起連接, STM

6、32 被動的處理整個TCP 過程?!?】PC 機試圖建立連接,發(fā)出SYN 標志。【 2】STM32 接收到 SYN 標志,響應(yīng) PC 機的連接請求,發(fā)送 SYN 和 ACK 標志【 3】PC 機收到 SYN 和 ACK 標志,發(fā)送 ACK 標志,表示TCP 連接建立【 4】PC 機在建立連接之后, 向 STM32 發(fā)送 TCP 負載數(shù)據(jù),并包含 PUSH 和 ACK 標志【5】STM32 收到負載數(shù)據(jù),返回應(yīng)答數(shù)據(jù),并包括FIN 、ACK 和 FUSH 標志(FIN 意味著 AVR 試圖停止本次TCP 連接)【6】PC 機對負載數(shù)據(jù)處理,返回ACK 標志【7】PC 機也發(fā)出 FIN 標志和 A

7、CK 標志,同意停止本次 TCP 連接【 8】STM32 收到該 FIN 標志,發(fā)出 ACK 標志,意味著本次 TCP 通信完全結(jié)束。TCP 的建立連接,收發(fā)數(shù)據(jù)和停止連接,配合定時器輔以有限狀態(tài)機是一個常用的實現(xiàn)方式,但實現(xiàn)這些功能需要成千上萬行代碼,通過分析可以看出?!?1】對于 FIN 標志和 SYN 標志,無論是服務(wù)端還是客戶端都需要發(fā)送 ACK 標志【 2】STM32 共 4 次收到 ACK 標志。第一次為上文的第3 步,該 ACK 位的接收表示TCP 連接成功,此時負載數(shù)據(jù)長度為 0,STM32 對該返回報文不做處理。 第二次收到 ACK 標志,發(fā)生在上文的 4 到 5 步,和上次

8、收到 ACK 不同,負載數(shù)據(jù)一定不為 0。第三次收到 ACK 標志,發(fā)生在第 6 步,此時負載數(shù)據(jù)長度也為 0, STM32 對該報文不做任何處理。第四次收到 ACK 標志發(fā)生在第 7 步, STM32 必須應(yīng)答,但是該報文也含有 FIN 標志,可以區(qū)別于以上幾種情況。STM32NET 項目便采用以上的方式區(qū)別TCP 數(shù)據(jù)包,通過 IF ELSE 實現(xiàn)了 TCP 狀態(tài)機。 STM32NET 項目先處理SYN 標志,接著檢查所有的 ACK 標志,若標志也含有 FIN 標志,則返回 ACK ,若負載數(shù)據(jù)長度為 0,不做響應(yīng),若負載數(shù)據(jù)大于 0,取出數(shù)據(jù)做出合適的響應(yīng)。2.2 TCP 序號和確認號T

9、CP 序號和確認號也是一個比較微妙的細節(jié)??偨Y(jié)起來有以下幾點?!?1】 TCP 的初始序號由發(fā)送 SYN 或發(fā)送 FIN 時決定?!?2】 TCP 建立連接時, PC 機發(fā)送 SYN 時設(shè)置初始序號,AVR 返回 SYN 和 ACK 時設(shè)置初始序號, 這兩個初始序號沒有任何邏輯上的關(guān)系。【 3】確認號為上一個數(shù)據(jù)包的序號加上個數(shù)據(jù)包的負載長度。【 4】 SYN 標志和 FIN 特殊,占用個序號,即確認號需在上個數(shù)據(jù)包的序號基礎(chǔ)累加。STM32NET 項目中何時清零序號,何時初始化序號,何時修改確認號,何時修改確認號的確是一個非常麻煩的過程。通過反復(fù)的測試,發(fā)現(xiàn)即使確認號出現(xiàn)問題程序也能順利運行

10、。3.TCP 實現(xiàn)從實用主義角度出發(fā),原理不重要,重要的是如何實現(xiàn)實現(xiàn)功能。和 UDP 不同, TCP 生成首部時的步驟較多。由于 TCP 首部中存在選項, 所以需要通過更多的代碼確定 TCP 負載的位置, 在這里可以分為在 TCP 首部中查找負載長度字節(jié),并通過首部中的 TCP 偏移字節(jié)確定長度3.1 TCP 數(shù)據(jù)發(fā)送TCP 發(fā)送時的參數(shù)很多,大致可以分為以下步驟?!?1】確定下一個確認號的具體值。使用時有兩種情況,那么累加 1,要么累加上一個報文的負載長度?!?2】初始化序號,可以在 ABRNET 作為客戶端時使用【 3】清除序號,可以在 TCP 建立連接時使用【 4】設(shè)置標志,例如 FI

11、N SYN 等【 5】設(shè)置其他參數(shù),例如緊急指針,窗口大小【 6】填充以太網(wǎng)首部, IP 首部【 7】加入校驗和cpp view plain copy void tcp_send_packet(BYTE *rxtx_buffer, / 發(fā)送緩沖區(qū)WORD_BYTES dest_port, /目標端口號WORD_BYTESsrc_port, / 源端口號BYTE flags,/ TCP 標志 FIN SYN ACKBYTE max_segment_size, / 初始化序號接收 SYN 時使用BYTE clear_seqack, / 設(shè)置確認號為 0發(fā)送 SYN 時使用WORD next_ack

12、_num, / 在上一個數(shù)據(jù)包序號的基礎(chǔ)上累加WORD dlength, /負載長度BYTE *dest_mac, /目標 MAC地址BYTE *dest_ip ) /目標 IP 地址BYTE i, tseq;WORD_BYTES ck;/ 生成以太網(wǎng)報文頭eth_generate_header ( rxtx_buffer,(WORD_BYTES)ETH_TYPE_IP_V, dest_mac );/ 計算數(shù)據(jù)包 確認號 next_ack_num 為累加值/ 1.確認號因等于上一個數(shù)據(jù)包的序號加上數(shù)據(jù)包長度/ 2.序號等于上一個數(shù)據(jù)包的確認號/ 3.FIN和 SYN 各占一個序號/ 4. 確認

13、號和序號使用大端模式,即高地址存放低位數(shù)據(jù)/ 5. 確認號修改發(fā)生在三種情況,接收到 SYN ,接收到FIN ,接收到負載數(shù)據(jù)if( next_ack_num )for( i = 4 ; i > 0; i- )/ 取出上一個數(shù)據(jù)包的序號,累加next_ack_numnext_ack_num = rxtx_buffer TCP_SEQ_P + i - 1 + next_ack_num;/ 取出上一個數(shù)據(jù)包的確認號tseq = rxtx_buffer TCP_SEQACK_P + i - 1;/復(fù)制本次數(shù)據(jù)包的確認號,即上個數(shù)據(jù)包的序號 +next_ack_numrxtx_buffer TC

14、P_SEQACK_P + i - 1 = 0xff &next_ack_num;/ 復(fù)制上一個數(shù)據(jù)包的確認號于本數(shù)據(jù)包的序號rxtx_buffer TCP_SEQ_P + i - 1 = tseq;next_ack_num >>= 8;/ 初始化序號/ 設(shè)置最大分片/第一次發(fā)送或接收時使用if ( max_segment_size )/ 初始化序號rxtx_buffer TCP_SEQ_P + 0 = 0;rxtx_buffer TCP_SEQ_P + 1 = 0;rxtx_buffer TCP_SEQ_P + 2 = seqnum;rxtx_buffer TCP_SEQ_

15、P + 3 = 0;seqnum += 2;/ 初始化 報文段最大長度rxtx_buffer TCP_OPTIONS_P + 0=2;/最大報文長度rxtx_buffer TCP_OPTIONS_P + 1 = 4; / TCP 選項長度TCP 選項格式 2rxtx_buffer TCP_OPTIONS_P +2 = HIGH(1408); /rxtx_buffer TCP_OPTIONS_P + 3 = LOW(1408); / 數(shù)據(jù)偏移,占用高 4 位,且計算長度為雙字rxtx_buffer TCP_HEADER_LEN_P = 0x60;dlength += 4;else/ 沒有TCP

16、選項時長度為5 個雙字rxtx_buffer TCP_HEADER_LEN_P = 0x50;/ generate ip header and checksumip_generate_header( rxtx_buffer, (WORD_BYTES)(IP_HEADER_LEN +TCP_HEADER_LEN + dlength), IP_PROTO_TCP_V,dest_ip );/ 清除序號,一般使用于發(fā)送SYN 時if ( clear_seqack ) rxtx_buffer TCP_SEQACK_P + 0 = 0; rxtx_buffer TCP_SEQACK_P + 1 = 0;r

17、xtx_buffer TCP_SEQACK_P + 2 = 0;rxtx_buffer TCP_SEQACK_P + 3 = 0;/ 設(shè)置 TCP 標志rxtx_buffer TCP_FLAGS_P = flags;/ 設(shè)置目標端口號rxtx_buffer TCP_DST_PORT_H_P = dest_port.byte.high;rxtx_buffer TCP_DST_PORT_L_P = dest_port.byte.low;/ 設(shè)置源端口號rxtx_buffer TCP_SRC_PORT_H_P = src_port.byte.high;rxtx_buffer TCP_SRC_PORT

18、_L_P = src_port.byte.low;/設(shè)置 TCP 窗口大小rxtx_buffer TCP_WINDOWSIZE_H_P =HIGH(MAX_RX_BUFFER-IP_HEADER_LEN-ETH_HEADER_LEN);rxtx_buffer TCP_WINDOWSIZE_L_P =LOW(MAX_RX_BUFFER-IP_HEADER_LEN-ETH_HEADER_LEN);/ 緊急指針rxtx_buffer TCP_URGENT_PTR_H_P = 0;rxtx_buffer TCP_URGENT_PTR_L_P = 0;/ 計算校驗和rxtx_buffer TCP_CHE

19、CKSUM_H_P = 0;rxtx_buffer TCP_CHECKSUM_L_P = 0;ck.word =software_checksum( &rxtx_bufferIP_SRC_IP_P, TCP_HEADER_LEN+dlength+8, IP_PROTO_TCP_V + TCP_HEADER_LEN + dlength );rxtx_buffer TCP_CHECKSUM_H_P = ck.byte.high; rxtx_buffer TCP_CHECKSUM_L_P = ck.byte.low;/ 通過 enc28j60 發(fā)送數(shù)據(jù)enc28j60_packet_send

20、( rxtx_buffer,ETH_HEADER_LEN+IP_HEADER_LEN+TCP_HEADER_LEN+dlength );3.2 TCP 負載長度查詢TCP 負載長度查詢需要根據(jù)IP 報文中數(shù)據(jù)包的總大小和 TCP 報文中的數(shù)據(jù)偏移量決定,并需要注意TCP 的數(shù)據(jù)偏移量的單位為雙字,即4 個字節(jié)長度。cpp view plaincopy WORD tcp_get_dlength ( BYTE *rxtx_buffer )int dlength, hlength;/ 獲得 IP 報文總大小dlength = ( rxtx_buffer IP_TOTLEN_H_P <<8

21、 ) |( rxtx_buffer IP_TOTLEN_L_P );/除去 IP 報文頭部大小dlength -= IP_HEADER_LEN;/獲得 TCP報文數(shù)據(jù)偏移量單位為字,需要X4hlength =(rxtx_buffer TCP_HEADER_LEN_P >>4) * 4;/除去 TCP 報文數(shù)據(jù)偏移量dlength -= hlength;if ( dlength <= 0 )dlength=0;return(WORD)dlength);3.3 TCP 負載位置查詢cpp view plain copy BYTEtcp_get_hlength ( BYTE *rx

22、tx_buffer )/ 獲得TCP報文數(shù)據(jù)偏移量單位為字,需要X4return(rxtx_buffer TCP_HEADER_LEN_P >>4) * 4); / generate len in bytes; 3.4 TCP 負載填充TCP 的負載數(shù)據(jù)填充和 UDP 的負載數(shù)據(jù)填充相似。 cpp view plain copy WORD tcp_puts_data ( BYTE *rxtx_buffer, BYTE *data, WORD offset )while( *data )rxtx_buffer TCP_DATA_P + offset = *data+;offset+;

23、return offset;3.5 TCP 數(shù)據(jù)包處理TCP 數(shù)據(jù)包的處理代碼較多,該函數(shù)會返回1 或0, 1代表以太網(wǎng)接收緩沖區(qū)的數(shù)據(jù)被處理,而0 代表數(shù)據(jù)尚未被處理。 TCP 數(shù)據(jù)包的處理包含具體的應(yīng)用實現(xiàn),該部分出現(xiàn)在服務(wù)器端第二次返回 ACK 之后,具體的代碼請結(jié)合范例和上文的 TCP 連接部分。cpp view plain copy BYTE tcp_receive ( BYTE *rxtx_buffer,BYTE *dest_mac, BYTE *dest_ip )WORDtcp_reclen, tcp_sendlen , dest_port;/ 獲得目標端口號 即客戶端端口號de

24、st_port =(rxtx_bufferTCP_SRC_PORT_H_P<<8)|rxtx_bufferTCP_SRC_PORT_L_P;/ 匹配 TCP 協(xié)議類型, 匹配端口if ( rxtx_buffer IP_PROTO_P = IP_PROTO_TCP_V&& rxtx_buffer TCP_DST_PORT_H_P = TCP_A VR_PORT_H_V&& rxtx_buffer TCP_DST_PORT_L_P = TCP_A VR_PORT_L_V )/ 服務(wù)器端第 1 次發(fā)送 收到 SYN 返回SYN+ACKif ( (rxtx_

25、buffer TCP_FLAGS_P & TCP_FLAG_SYN_V) )tcp_send_packet(rxtx_buffer, / 發(fā)送緩沖區(qū)(WORD_BYTES)dest_port, /目標端口號(WORD_BYTES)TCP_AVR_PORT_V, /源端口號TCP_FLAG_SYN_V|TCP_FLAG_ACK_V, /標志位同步位和應(yīng)答位1, /初始化序號,只有在接收到SYN時使用0, /不清除確認號1, /確認號為上一個數(shù)據(jù)包的應(yīng)答編號加1,SYN占用一個序號0, / 負載長度dest_mac,/ 客戶端 MAC 地址dest_ip / 客戶端 IP 地址);retu

26、rn 1;/ 收到 ACK多種情況if ( (rxtx_buffer TCP_FLAGS_P & TCP_FLAG_ACK_V) )獲得 TCP 負載長度tcp_reclen =報文/tcp_get_dlength( rxtx_buffer );if ( tcp_reclen = 0 )/服務(wù)器第4 次發(fā)送,收到FIN ,返回ACK/ 主要是為了區(qū)別 建立連接時的最后一個 ACKif ( (rxtx_bufferTCP_FLAGS_P & TCP_FLAG_FIN_V) )tcp_send_packet(rxtx_buffer, /發(fā)送緩沖區(qū)(WORD_BYTES)dest_p

27、ort, /目標端口(WORD_BYTES)TCP_AVR_PORT_V, /源端口TCP_FLAG_ACK_V , / 標志位應(yīng)答0, / 不操作序號0, / 不清楚確認號1, / FIN 占一個序號,在一個數(shù)據(jù)包的序號的基礎(chǔ)上累加10, / 負載大小dest_mac, / 客戶端 MAC 地址dest_ip / 客戶端 IP 地址);return 1;/服務(wù)器第 2 次發(fā)送,返回ACKtcp_send_packet(rxtx_buffer, /發(fā)送緩沖區(qū)(WORD_BYTES)dest_port, /目標端口號(WORD_BYTES)TCP_A VR_PORT_V, / 源端口號 TCP_

28、FLAG_ACK_V , / 標志位 應(yīng)答標志0, / 不操作序號0,/ 不清除確認號tcp_reclen, /在上一個數(shù)據(jù)包的基礎(chǔ)上累加tcp_reclen0, / 負載長度dest_mac,/ 客戶端 MAC 地址dest_ip ); / 客戶端 IP 地址/確定 TCP 負載位置WORD tcp_loadpos =tcp_get_hlength( rxtx_buffer) + ETH_HEADER_LEN +IP_HEADER_LEN;/ 復(fù)制緩沖區(qū)數(shù)據(jù)memcpy(tcp_recbuf,(char*)&rxtx_buffertcp_loadpos,tcp_reclen);/ 范

29、例 1 TCP:Hello/準備返回數(shù)據(jù)strcpy(tcp_sendbuf,TCP:Hello );strcat(tcp_sendbuf,tcp_recbuf);/ 填充緩沖區(qū)tcp_sendlen =tcp_puts_data( rxtx_buffer,(BYTE*)tcp_sendbuf,0);/ 服務(wù)器第 3 次發(fā)送,發(fā)送 HTTP 響應(yīng) 發(fā)送 FIN tcp_send_packet(rxtx_buffer, /發(fā)送緩沖區(qū)(WORD_BYTES)dest_port, /目標端口(WORD_BYTES)TCP_AVR_PORT_V, /源端口/ 標志TCP_FLAG_ACK_V | TC

30、P_FLAG_PSH_V | TCP_FLAG_FIN_V ,0, /不操作序號0, /不清除確認號0, /tcp_sendlen, /負載長度dest_mac, /客戶端MAC地址dest_ip ); /客戶端IP地址/ 數(shù)據(jù)包被處理return 1;/ 返回0代表數(shù)據(jù)未被處理return 0;4.實驗TCP 報文的處理位于ARP、 IP、 ICMP 和 ICMP 之后。獲得TCP有效負載之后應(yīng)存在在接收緩沖區(qū)中,進行合適的處理并返回結(jié)果。實驗通過兩個例子說明TCP的使用。4.1 程序結(jié)構(gòu)cpp view plain copy void server_process ( void )MAC_

31、ADDR client_mac;IP_ADDR client_ip;WORD plen;/ 獲得新的 IP 報文plen =enc28j60_packet_receive( (BYTE*)&rxtx_buffer,MAX_RXTX_BUFFER );if(plen=0) return;/ 保存客服端的MAC 地址memcpy( (BYTE*)&client_mac,&rxtx_buffer ETH_SRC_MAC_P ,sizeof( MAC_ADDR) );/ 檢查該報文是不是ARP 報文if ( arp_packet_is_arp( rxtx_buffer,(WOR

32、D_BYTES)ARP_OPCODE_REQUEST_V ) )/向客戶端返回ARP 報文arp_send_reply ( (BYTE*)&rxtx_buffer,(BYTE*)&client_mac );return;/保存客服端的 IP 地址memcpy( (BYTE*)&client_ip, &rxtx_buffer IP_SRC_IP_P ,sizeof(IP_ADDR) );/檢查該報文是否為IP 報文if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) = 0 )return;/ 如果是 ICMP 報文向發(fā)

33、起方返回數(shù)據(jù)if ( icmp_send_reply( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac,(BYTE*)&client_ip ) )return;/ 進行 UDP 處理 if (udp_receive ( (BYTE *)&rxtx_buffer, (BYTE *)&client_mac, (BYTE*)&client_ip )return;進行 TCP 處理if (tcp_receive ( (BYTE*)&rxtx_buffer, (BYTE *)&client_mac, (BYTE*)&client_ip )return;/4.2 TCP Hello接收到 TCP 數(shù)據(jù)包之后,在負載數(shù)據(jù)之前加入Hello 字符串,如果輸入為xukai871105 ,則返回 Hello xukai871105 。通過網(wǎng)絡(luò)調(diào)試助手查看返回結(jié)果。使用strcpy 函數(shù)把 Hello復(fù)制到 tcp_sendbuf 數(shù)組中,接著使用 strcat 把 tcp_recbuf 中的字符串連接到 tcp_sendbuf 之后,最后調(diào)用 tcp_send_packet填充到發(fā)送緩沖區(qū)中。cpp view plain copy #if T

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論