go語(yǔ)言tcpsyn go語(yǔ)言tcp發(fā)送圖片

go語(yǔ)言TCP連接池rocket049/connpool使用

安裝:

成都創(chuàng)新互聯(lián)專注網(wǎng)站設(shè)計(jì),以設(shè)計(jì)驅(qū)動(dòng)企業(yè)價(jià)值的持續(xù)增長(zhǎng),網(wǎng)站,看似簡(jiǎn)單卻每一個(gè)企業(yè)都需要——設(shè)計(jì),看似簡(jiǎn)潔卻是每一位設(shè)計(jì)師的心血 十載來(lái),我們只專注做網(wǎng)站。認(rèn)真對(duì)待每一個(gè)客戶,我們不用口頭的語(yǔ)言來(lái)吹擂我們的優(yōu)秀,數(shù)千家的成功案例見證著我們的成長(zhǎng)。

go get -v -u github.com/rocket049/connpool

go get -v -u gitee.com/rocket049/connpool

rocket049/connpool 包是本人用go語(yǔ)言開發(fā)的,提供一個(gè)通用的TCP連接池,初始化參數(shù)包括最高連接數(shù)、超時(shí)秒數(shù)、連接函數(shù),放回連接池的連接被重新取出時(shí),如果已經(jīng)超時(shí),將會(huì)自動(dòng)重新連接;如果沒有超時(shí),連接將被復(fù)用。

可調(diào)用的函數(shù):

調(diào)用示例:

Go 語(yǔ)言自我提升 (三次握手 - 四次揮手 - TCP狀態(tài)圖 - udp - 網(wǎng)絡(luò)文件傳輸)

三次握手:

1. 主動(dòng)發(fā)起連接請(qǐng)求端(客戶端),發(fā)送 SYN 標(biāo)志位,攜帶數(shù)據(jù)包、包號(hào)

2. 被動(dòng)接收連接請(qǐng)求端(服務(wù)器),接收 SYN,回復(fù) ACK,攜帶應(yīng)答序列號(hào)。同時(shí),發(fā)送SYN標(biāo)志位,攜帶數(shù)據(jù)包、包號(hào)

3. 主動(dòng)發(fā)起連接請(qǐng)求端(客戶端),接收SYN 標(biāo)志位,回復(fù) ACK。

被動(dòng)端(服務(wù)器)接收 ACK —— 標(biāo)志著 三次握手建立完成( Accept()/Dial() 返回 )

四次揮手:

1. 主動(dòng)請(qǐng)求斷開連接端(客戶端), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包

2. 被動(dòng)接受斷開連接端(服務(wù)器), 發(fā)送 ACK標(biāo)志,攜帶應(yīng)答序列號(hào)。 —— 半關(guān)閉完成。

3. 被動(dòng)接受斷開連接端(服務(wù)器), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包

4. 主動(dòng)請(qǐng)求斷開連接端(客戶端), 發(fā)送 最后一個(gè) ACK標(biāo)志,攜帶應(yīng)答序列號(hào)。—— 發(fā)送完成,客戶端不會(huì)直接退出,等 2MSL時(shí)長(zhǎng)。

等 2MSL待目的:確保服務(wù)器 收到最后一個(gè)ACK

滑動(dòng)窗口:

通知對(duì)端本地存儲(chǔ)數(shù)據(jù)的 緩沖區(qū)容量?!?write 函數(shù)在對(duì)端 緩沖區(qū)滿時(shí),有可能阻塞。

TCP狀態(tài)轉(zhuǎn)換:

1. 主動(dòng)發(fā)起連接請(qǐng)求端:

CLOSED —— 發(fā)送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回發(fā) ACK —— ESTABLISHED (數(shù)據(jù)通信)

2. 主動(dòng)關(guān)閉連接請(qǐng)求端:

ESTABLISHED —— 發(fā)送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半關(guān)閉、主動(dòng)端)

—— 接收FIN、回復(fù)ACK —— TIME_WAIT (主動(dòng)端) —— 等 2MSL 時(shí)長(zhǎng) —— CLOSED

3. 被動(dòng)建立連接請(qǐng)求端:

CLOSED —— LISTEN —— 接收SYN、發(fā)送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (數(shù)據(jù)通信)

4. 被動(dòng)斷開連接請(qǐng)求端:

ESTABLISHED —— 接收 FIN、發(fā)送 ACK —— CLOSE_WAIT —— 發(fā)送 FIN —— LAST_ACK —— 接收ACK —— CLOSED

windows下查看TCP狀態(tài)轉(zhuǎn)換:

netstat -an | findstr? 端口號(hào)

Linux下查看TCP狀態(tài)轉(zhuǎn)換:

netstat -an | grep? 端口號(hào)

TCP和UDP對(duì)比:?

TCP: 面向連接的可靠的數(shù)據(jù)包傳遞。 針對(duì)不穩(wěn)定的 網(wǎng)絡(luò)層,完全彌補(bǔ)。ACK

UDP:無(wú)連接不可靠的報(bào)文傳輸。 針對(duì)不穩(wěn)定的 網(wǎng)絡(luò)層,完全不彌補(bǔ)。還原網(wǎng)絡(luò)真實(shí)狀態(tài)。

優(yōu)點(diǎn)???????????????????????????????????????????????????????????? 缺點(diǎn)

TCP: 可靠、順序、穩(wěn)定 ???????????????????????????????????? 系統(tǒng)資源消耗大,程序?qū)崿F(xiàn)繁復(fù)、速度慢

UDP:系統(tǒng)資源消耗小,程序?qū)崿F(xiàn)簡(jiǎn)單、速度快 ???????????????????????? 不可靠、無(wú)序、不穩(wěn)定

使用場(chǎng)景:

TCP:大文件、可靠數(shù)據(jù)傳輸。 對(duì)數(shù)據(jù)的 穩(wěn)定性、準(zhǔn)確性、一致性要求較高的場(chǎng)合。

UDP:應(yīng)用于對(duì)數(shù)據(jù)時(shí)效性要求較高的場(chǎng)合。 網(wǎng)絡(luò)直播、電話會(huì)議、視頻直播、網(wǎng)絡(luò)游戲。

UDP-CS-Server實(shí)現(xiàn)流程:

1.? 創(chuàng)建 udp地址結(jié)構(gòu) ResolveUDPAddr(“協(xié)議”, “IP:port”) —— udpAddr 本質(zhì) struct{IP、port}

2.? 創(chuàng)建用于 數(shù)據(jù)通信的 socket ListenUDP(“協(xié)議”, udpAddr ) —— udpConn (socket)

3.? 從客戶端讀取數(shù)據(jù),獲取對(duì)端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err

4.? 發(fā)送數(shù)據(jù)包給 客戶端 udpConn.WriteToUDP("數(shù)據(jù)", clientAddr)

UDP-CS-Client實(shí)現(xiàn)流程:

1.? 創(chuàng)建用于通信的 socket。 net.Dial("udp", "服務(wù)器IP:port") —— udpConn (socket)

2.? 以后流程參見 TCP客戶端實(shí)現(xiàn)源碼。

UDPserver默認(rèn)就支持并發(fā)!

------------------------------------

命令行參數(shù): 在main函數(shù)啟動(dòng)時(shí),向整個(gè)程序傳參。 【重點(diǎn)】

語(yǔ)法: go run xxx.go ? argv1 argv2? argv3? argv4 。。。

xxx.exe:? 第 0 個(gè)參數(shù)。

argv1 :第 1 個(gè)參數(shù)。

argv2 :第 2 個(gè)參數(shù)。

argv3 :第 3 個(gè)參數(shù)。

argv4 :第 4 個(gè)參數(shù)。

使用: list := os.Args? 提取所有命令行參數(shù)。

獲取文件屬性函數(shù):

os.stat(文件訪問(wèn)絕對(duì)路徑) —— fileInfo 接口

fileInfo 包含 兩個(gè)接口。

Name() 獲取文件名。 不帶訪問(wèn)路徑

Size() 獲取文件大小。

網(wǎng)絡(luò)文件傳輸 —— 發(fā)送端(客戶端)

1.? 獲取命令行參數(shù),得到文件名(帶路徑)filePath list := os.Args

2.? 使用 os.stat() 獲取 文件名(不帶路徑)fileName

3.? 創(chuàng)建 用于數(shù)據(jù)傳輸?shù)?socket? net.Dial("tcp", “服務(wù)器IP+port”) —— conn

4.? 發(fā)送文件名(不帶路徑)? 給接收端, conn.write()

5.? 讀取 接收端回發(fā)“ok”,判斷無(wú)誤。封裝函數(shù) sendFile(filePath, conn) 發(fā)送文件內(nèi)容

6.? 實(shí)現(xiàn) sendFile(filePath,? conn)

1) 只讀打開文件 os.Open(filePath)

for {

2) 從文件中讀數(shù)據(jù)? f.Read(buf)

3) 將讀到的數(shù)據(jù)寫到socket中? conn.write(buf[:n])

4)判斷讀取文件的 結(jié)尾。 io.EOF. 跳出循環(huán)

}

網(wǎng)絡(luò)文件傳輸 —— 接收端(服務(wù)器)

1. 創(chuàng)建用于監(jiān)聽的 socket net.Listen() —— listener

2. 借助listener 創(chuàng)建用于 通信的 socket listener.Accpet()? —— conn

3. 讀取 conn.read() 發(fā)送端的 文件名, 保存至本地。

4. 回發(fā) “ok”應(yīng)答 發(fā)送端。

5. 封裝函數(shù),接收文件內(nèi)容 recvFile(文件路徑)

1) f = os.Create(帶有路徑的文件名)

for {

2)從 socket中讀取發(fā)送端發(fā)送的 文件內(nèi)容 。 conn.read(buf)

3)? 將讀到的數(shù)據(jù) 保存至本地文件 f.Write(buf[:n])

4)? 判斷 讀取conn 結(jié)束, 代表文件傳輸完成。 n == 0? break

}

go語(yǔ)言tcp客戶端怎么和服務(wù)端鏈接

網(wǎng)絡(luò)連接需要用socket,易語(yǔ)言用查易語(yǔ)言socket用或者看看否TCP協(xié)議相關(guān)組件

TCP那些事兒

目錄:

以前我也認(rèn)為TCP是相當(dāng)?shù)讓拥臇|西,我永遠(yuǎn)不需要去了解它。雖然差不多是這樣,但是實(shí)際生活中,你依然可能遇見和TCP算法相關(guān)的bug,這時(shí)候懂一些TCP的知識(shí)就至關(guān)重要了。( 本文也可以引申為,系統(tǒng)調(diào)用,操作系統(tǒng)這些都很重要,這個(gè)道理適用于很多東西 )

這里推薦一篇小短文, 人人都應(yīng)該懂點(diǎn)TCP

使用TCP協(xié)議通信的雙方必須先建立TCP連接,并在內(nèi)核中為該連接維持一些必要的數(shù)據(jù)結(jié)構(gòu),比如連接的狀態(tài)、讀寫緩沖區(qū)、定時(shí)器等。當(dāng)通信結(jié)束時(shí),雙方必須關(guān)閉連接以釋放這些內(nèi)核數(shù)據(jù)。TCP服務(wù)基于流,源源不斷從一端流向另一端,發(fā)送端可以逐字節(jié)寫入,接收端可以逐字節(jié)讀出,無(wú)需分段。

需要注意的幾點(diǎn):

TCP狀態(tài)(11種):

eg.

以上為TCP三次握手的狀態(tài)變遷

以下為TCP四次揮手的狀態(tài)變遷

服務(wù)器通過(guò) listen 系統(tǒng)調(diào)用進(jìn)入 LISTEN 狀態(tài),被動(dòng)等待客戶端連接,也就是所謂的被動(dòng)打開。一旦監(jiān)聽到SYN(同步報(bào)文段)請(qǐng)求,就將該連接放入內(nèi)核的等待隊(duì)列,并向客戶端發(fā)送帶SYN的ACK(確認(rèn)報(bào)文段),此時(shí)該連接處于 SYN_RECVD 狀態(tài)。如果服務(wù)器收到客戶端返回的ACK,則轉(zhuǎn)到 ESTABLISHED 狀態(tài)。這個(gè)狀態(tài)就是連接雙方能進(jìn)行全雙工數(shù)據(jù)傳輸?shù)臓顟B(tài)。

而當(dāng)客戶端主動(dòng)關(guān)閉連接時(shí),服務(wù)器收到FIN報(bào)文,通過(guò)返回ACK使連接進(jìn)入 CLOSE_WAIT 狀態(tài)。此狀態(tài)表示——等待服務(wù)器應(yīng)用程序關(guān)閉連接。通常,服務(wù)器檢測(cè)到客戶端關(guān)閉連接之后,也會(huì)立即給客戶端發(fā)送一個(gè)FIN來(lái)關(guān)閉連接,使連接轉(zhuǎn)移到 LAST_ACK 狀態(tài),等待客戶端對(duì)最后一個(gè)FIN結(jié)束報(bào)文段的最后一次確認(rèn),一旦確認(rèn)完成,連接就徹底關(guān)閉了。

客戶端通過(guò) connect 系統(tǒng)調(diào)用主動(dòng)與服務(wù)器建立連接。此系統(tǒng)調(diào)用會(huì)首先給服務(wù)器發(fā)一個(gè)SYN,使連接進(jìn)入 SYN_SENT 狀態(tài)。

connect 調(diào)用可能因?yàn)閮煞N原因失敗:1. 目標(biāo)端口不存在(未被任何進(jìn)程監(jiān)聽)護(hù)著該端口被 TIME_WAIT 狀態(tài)的連接占用( 詳見后文 )。2. 連接超時(shí),在超時(shí)時(shí)間內(nèi)未收到服務(wù)器的ACK。

如果 connect 調(diào)用失敗,則連接返回初始的 CLOSED 狀態(tài),如果調(diào)用成功,則轉(zhuǎn)到 ESTABLISHED 狀態(tài)。

客戶端執(zhí)行主動(dòng)關(guān)閉時(shí),它會(huì)向服務(wù)器發(fā)送一個(gè)FIN,連接進(jìn)入 TIME_WAIT_1 狀態(tài),如果收到服務(wù)器的ACK,進(jìn)入 TIME_WAIT_2 狀態(tài)。此時(shí)服務(wù)器處于 CLOSE_WAIT 狀態(tài),這一對(duì)狀態(tài)是可能發(fā)生辦關(guān)閉的狀態(tài)(詳見后文)。此時(shí)如果服務(wù)器發(fā)送FIN關(guān)閉連接,則客戶端會(huì)發(fā)送ACK進(jìn)行確認(rèn)并進(jìn)入 TIME_WAIT 狀態(tài)。

流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來(lái)得及接收。

接收方發(fā)送的確認(rèn)報(bào)文中的窗口字段可以用來(lái)控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將窗口字段設(shè)置為 0,則發(fā)送方不能發(fā)送數(shù)據(jù)。

如果網(wǎng)絡(luò)出現(xiàn)擁塞,分組將會(huì)丟失,此時(shí)發(fā)送方會(huì)繼續(xù)重傳,從而導(dǎo)致網(wǎng)絡(luò)擁塞程度更高。因此當(dāng)出現(xiàn)擁塞時(shí),應(yīng)當(dāng)控制發(fā)送方的速率。這一點(diǎn)和流量控制很像,但是出發(fā)點(diǎn)不同。 流量控制是為了讓接收方能來(lái)得及接收,而擁塞控制是為了降低整個(gè)網(wǎng)絡(luò)的擁塞程度。

TCP 主要通過(guò)四種算法來(lái)進(jìn)行擁塞控制: 慢開始、擁塞避免、快重傳、快恢復(fù)。

在Linux下有多種實(shí)現(xiàn),比如reno算法,vegas算法和cubic算法等。

發(fā)送方需要維護(hù)一個(gè)叫做擁塞窗口(cwnd)的狀態(tài)變量,注意擁塞窗口與發(fā)送方窗口的區(qū)別:擁塞窗口只是一個(gè)狀態(tài)變量,實(shí)際決定發(fā)送方能發(fā)送多少數(shù)據(jù)的是發(fā)送方窗口。

為了便于討論,做如下假設(shè):

發(fā)送的最初執(zhí)行慢開始,令 cwnd=1,發(fā)送方只能發(fā)送 1 個(gè)報(bào)文段;當(dāng)收到確認(rèn)后,將 cwnd 加倍,因此之后發(fā)送方能夠發(fā)送的報(bào)文段數(shù)量為:2、4、8 ...

注意到慢開始每個(gè)輪次都將 cwnd 加倍,這樣會(huì)讓 cwnd 增長(zhǎng)速度非??欤瑥亩沟冒l(fā)送方發(fā)送的速度增長(zhǎng)速度過(guò)快,網(wǎng)絡(luò)擁塞的可能也就更高。設(shè)置一個(gè)慢開始門限 ssthresh,當(dāng) cwnd = ssthresh 時(shí),進(jìn)入擁塞避免,每個(gè)輪次只將 cwnd 加 1。

如果出現(xiàn)了超時(shí),則令 ssthresh = cwnd/2,然后重新執(zhí)行慢開始。

在接收方,要求每次接收到報(bào)文段都應(yīng)該對(duì)最后一個(gè)已收到的有序報(bào)文段進(jìn)行確認(rèn)。例如已經(jīng)接收到 M1 和 M2,此時(shí)收到 M4,應(yīng)當(dāng)發(fā)送對(duì) M2 的確認(rèn)。

在發(fā)送方,如果收到三個(gè)重復(fù)確認(rèn),那么可以知道下一個(gè)報(bào)文段丟失,此時(shí)執(zhí)行快重傳,立即重傳下一個(gè)報(bào)文段。例如收到三個(gè) M2,則 M3 丟失,立即重傳 M3。

在這種情況下,只是丟失個(gè)別報(bào)文段,而不是網(wǎng)絡(luò)擁塞。因此執(zhí)行快恢復(fù),令 ssthresh = cwnd/2 ,cwnd = ssthresh,注意到此時(shí)直接進(jìn)入擁塞避免。

慢開始和快恢復(fù)的快慢指的是 cwnd 的設(shè)定值,而不是 cwnd 的增長(zhǎng)速率。慢開始 cwnd 設(shè)定為 1,而快恢復(fù) cwnd 設(shè)定為 ssthresh。

??發(fā)送端的每個(gè)TCP報(bào)文都必須得到接收方的應(yīng)答,才算傳輸成功。

??TCP為每個(gè)TCP報(bào)文段都維護(hù)一個(gè)重傳定時(shí)器。

??發(fā)送端在發(fā)出一個(gè)TCP報(bào)文段之后就啟動(dòng)定時(shí)器,如果在定時(shí)時(shí)間類未收到應(yīng)答,它就將重發(fā)該報(bào)文段并重置定時(shí)器。

??因?yàn)門CP報(bào)文段最終在網(wǎng)絡(luò)層是以IP數(shù)據(jù)報(bào)的形式發(fā)送,而IP數(shù)據(jù)報(bào)到達(dá)接收端可能是亂序或者重復(fù)的。TCP協(xié)議會(huì)對(duì)收到的TCP報(bào)文進(jìn)行重排、整理,確保順序正確。

TCP報(bào)文段所攜帶的應(yīng)用程序數(shù)據(jù)按照長(zhǎng)度分為兩種: 交互數(shù)據(jù) 和 成塊數(shù)據(jù)

對(duì)于什么是粘包、拆包問(wèn)題,我想先舉兩個(gè)簡(jiǎn)單的應(yīng)用場(chǎng)景:

對(duì)于第一種情況,服務(wù)端的處理流程可以是這樣的:當(dāng)客戶端與服務(wù)端的連接建立成功之后,服務(wù)端不斷讀取客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),當(dāng)客戶端與服務(wù)端連接斷開之后,服務(wù)端知道已經(jīng)讀完了一條消息,然后進(jìn)行解碼和后續(xù)處理...。對(duì)于第二種情況,如果按照上面相同的處理邏輯來(lái)處理,那就有問(wèn)題了,我們來(lái)看看 第二種情況 下客戶端發(fā)送的兩條消息遞交到服務(wù)端有可能出現(xiàn)的情況:

第一種情況:

服務(wù)端一共讀到兩個(gè)數(shù)據(jù)包,第一個(gè)包包含客戶端發(fā)出的第一條消息的完整信息,第二個(gè)包包含客戶端發(fā)出的第二條消息,那這種情況比較好處理,服務(wù)器只需要簡(jiǎn)單的從網(wǎng)絡(luò)緩沖區(qū)去讀就好了,第一次讀到第一條消息的完整信息,消費(fèi)完再?gòu)木W(wǎng)絡(luò)緩沖區(qū)將第二條完整消息讀出來(lái)消費(fèi)。

第二種情況:

服務(wù)端一共就讀到一個(gè)數(shù)據(jù)包,這個(gè)數(shù)據(jù)包包含客戶端發(fā)出的兩條消息的完整信息,這個(gè)時(shí)候基于之前邏輯實(shí)現(xiàn)的服務(wù)端就蒙了,因?yàn)榉?wù)端不知道第一條消息從哪兒結(jié)束和第二條消息從哪兒開始,這種情況其實(shí)是發(fā)生了TCP粘包。

第三種情況:

服務(wù)端一共收到了兩個(gè)數(shù)據(jù)包,第一個(gè)數(shù)據(jù)包只包含了第一條消息的一部分,第一條消息的后半部分和第二條消息都在第二個(gè)數(shù)據(jù)包中,或者是第一個(gè)數(shù)據(jù)包包含了第一條消息的完整信息和第二條消息的一部分信息,第二個(gè)數(shù)據(jù)包包含了第二條消息的剩下部分,這種情況其實(shí)是發(fā)送了TCP拆,因?yàn)榘l(fā)生了一條消息被拆分在兩個(gè)包里面發(fā)送了,同樣上面的服務(wù)器邏輯對(duì)于這種情況是不好處理的。

我們知道tcp是以流動(dòng)的方式傳輸數(shù)據(jù),傳輸?shù)淖钚挝粸橐粋€(gè)報(bào)文段(segment)。tcp Header中有個(gè)Options標(biāo)識(shí)位,常見的標(biāo)識(shí)為mss(Maximum Segment Size)指的是,連接層每次傳輸?shù)臄?shù)據(jù)有個(gè)最大限制MTU(Maximum Transmission Unit),一般是1500比特,超過(guò)這個(gè)量要分成多個(gè)報(bào)文段,mss則是這個(gè)最大限制減去TCP的header,光是要傳輸?shù)臄?shù)據(jù)的大小,一般為1460比特。換算成字節(jié),也就是180多字節(jié)。

tcp為提高性能,發(fā)送端會(huì)將需要發(fā)送的數(shù)據(jù)發(fā)送到緩沖區(qū),等待緩沖區(qū)滿了之后,再將緩沖中的數(shù)據(jù)發(fā)送到接收方。同理,接收方也有緩沖區(qū)這樣的機(jī)制,來(lái)接收數(shù)據(jù)。

發(fā)生TCP粘包、拆包主要是由于下面一些原因:

既然知道了tcp是無(wú)界的數(shù)據(jù)流,且協(xié)議本身無(wú)法避免粘包,拆包的發(fā)生,那我們只能在應(yīng)用層數(shù)據(jù)協(xié)議上,加以控制。通常在制定傳輸數(shù)據(jù)時(shí),可以使用如下方法:

寫了一個(gè)簡(jiǎn)單的 golang 版的tcp服務(wù)器實(shí)例,僅供參考:

例子

參考和推薦閱讀書目:

注釋:

eg.

go語(yǔ)言中的tcpconn是阻塞還是非阻塞的

阻塞socket和非阻塞socket的區(qū)別: 1、讀操作 對(duì)于阻塞的socket,當(dāng)socket的接收緩沖區(qū)中沒有數(shù)據(jù)時(shí),read調(diào)用會(huì)一直阻塞住,直到有數(shù)據(jù)到來(lái)才返回。當(dāng)socket緩沖區(qū)中的數(shù)據(jù)量小于期望讀取的數(shù)據(jù)量時(shí),返回實(shí)際讀取的字節(jié)數(shù)。

網(wǎng)站欄目:go語(yǔ)言tcpsyn go語(yǔ)言tcp發(fā)送圖片
當(dāng)前鏈接:http://muchs.cn/article26/dooojcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、網(wǎng)站策劃、網(wǎng)站排名做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作