chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子百科>通信技術(shù)>數(shù)據(jù)通信>

windows遠(yuǎn)程桌面 - 基于TCP流協(xié)議的數(shù)據(jù)包通訊

2017年11月27日 14:29 網(wǎng)絡(luò)整理 作者: 用戶評(píng)論(0

  windows遠(yuǎn)程桌面:

  使用遠(yuǎn)程桌面可以遠(yuǎn)程控制另一臺(tái)windows機(jī)器,可以在遠(yuǎn)程桌面里做任何本地桌面上的操作,比如刪除,復(fù)制文件,可以把本地文件復(fù)制到遠(yuǎn)程機(jī)器里,在復(fù)制的同時(shí)還能執(zhí)行其他操作,遠(yuǎn)程機(jī)器的桌面變化實(shí)時(shí)更新到本地,等等。

  但是仔細(xì)研究會(huì)發(fā)現(xiàn),遠(yuǎn)程桌面只使用了一條 TCP連接,連接到被控制機(jī)器的 3389 端口。也就是在一條TCP通訊連接里,傳輸各種請(qǐng)求數(shù)據(jù)和接收各種應(yīng)答數(shù)據(jù)。遠(yuǎn)程桌面使用的是 RDP協(xié)議,我們這里不討論RDP的細(xì)節(jié),只討論如何在一條TCP連接中,如何做到遠(yuǎn)程桌面的各種操作。如果我們還是按照請(qǐng)求-應(yīng)答的模式來解釋遠(yuǎn)程桌面的通訊協(xié)議,顯然會(huì)有很多無法處理的問題。

  比如舉個(gè)簡(jiǎn)單例子:

  我們?cè)谶h(yuǎn)程桌面客戶端點(diǎn)擊鼠標(biāo)操作,這個(gè)操作會(huì)通過3389的TCP連接發(fā)送到被控制端,如果按照請(qǐng)求-應(yīng)答模式來工作,則必須在被控制端接收到這個(gè)鼠標(biāo)操作,執(zhí)行這個(gè)動(dòng)作,然后回答給客戶端已經(jīng)執(zhí)行了這個(gè)操作。如果這期間,被控制機(jī)器的桌面界面內(nèi)容發(fā)生變化,則無法通知給客戶端,因?yàn)橐磺型ㄓ嵍际前凑湛蛻舳税l(fā)起請(qǐng)求,然后服務(wù)端應(yīng)答的方式通訊的。即使我們使用請(qǐng)求-應(yīng)答的方式,通過輪詢定時(shí)查詢被控制機(jī)器的界面內(nèi)容變化情況,也無法做到實(shí)時(shí),而且輪詢慢了會(huì)嚴(yán)重影響視覺效果,輪詢快了會(huì)嚴(yán)重浪費(fèi)資源。

  于是,我們改換一種解決問題的辦法,從 UDP 通訊的特點(diǎn):(按照包模式通訊)入手去解決上邊的問題。假定我們?cè)谶h(yuǎn)程桌面的TCP通訊中,一切通訊的數(shù)據(jù)都定義成一個(gè)一個(gè)的單獨(dú)的數(shù)據(jù)包在同一條TCP連接中傳輸,數(shù)據(jù)包的接收和發(fā)送分開進(jìn)行,就是在同一個(gè)TCP連接中,一個(gè)線程專門接收數(shù)據(jù)包,一個(gè)線程專門發(fā)送數(shù)據(jù)包。這是可以的,因?yàn)楝F(xiàn)在的網(wǎng)卡都是工作在全雙工狀態(tài)下。所謂全雙工,就是接收和發(fā)送使用各自的通道,能獨(dú)立進(jìn)行數(shù)據(jù)傳輸。

  大致偽代碼如下:

  int tcp_socket = 客戶端連接到服務(wù)端的socket或者服務(wù)端接收到客戶端連接的socket。

  receive_thread() //負(fù)責(zé)接收數(shù)據(jù)包的線程

  {

  tcp_packet = recv_packet (tcp_socket );

  ////TCP 是流協(xié)議,因此,我們必須至少定義一個(gè)表示包大小的頭+包內(nèi)容,才能保證TCP數(shù)據(jù)傳輸?shù)耐健?/p>

  //處理 tcp_packet 包,為了不阻塞讀線程,一般是把tcp_packet交給別的線程處理。

  }

  send_thread()//負(fù)責(zé)發(fā)送數(shù)據(jù)包的線程

  {

  while(loop){

  從發(fā)送隊(duì)列取出一個(gè)包 tcp_packet,(發(fā)送隊(duì)列,是別的線程生成的需要發(fā)送的數(shù)據(jù)包。)

  send_packet( tcp_socket, tcp_packet ); //發(fā)送這個(gè)數(shù)據(jù)包。

  }

  }

  再回到上邊的問題,

  遠(yuǎn)程桌面控制端(客戶端)和被控制端(服務(wù)端),分別開啟兩個(gè)線程,一個(gè)負(fù)責(zé)接收數(shù)據(jù)包,一個(gè)負(fù)責(zé)發(fā)送數(shù)據(jù)包。當(dāng)我們?cè)谶h(yuǎn)程桌面客戶端點(diǎn)擊鼠標(biāo)等操作,生成一個(gè)鼠標(biāo)的數(shù)據(jù)包投遞到發(fā)送線程,發(fā)送線程再把它傳輸?shù)奖豢刂贫?,被控制端接收到這個(gè)數(shù)據(jù)包,然后執(zhí)行,他如果要回復(fù)這個(gè)鼠標(biāo)的執(zhí)行結(jié)果,則再生成一個(gè)結(jié)果包投遞到發(fā)送線程,發(fā)送線程再把這個(gè)包傳輸給客戶端。

  同時(shí)如果被控制端的界面發(fā)生改變,則生成一個(gè)界面內(nèi)容改變的數(shù)據(jù)包,投遞到發(fā)送線程,發(fā)送線程再傳輸給客戶端。客戶端的接收線程接收到界面內(nèi)容改變的數(shù)據(jù)包,顯示新的被控制端的界面內(nèi)容??蛻舳私邮盏绞髽?biāo)執(zhí)行結(jié)果的包,知道鼠標(biāo)操作是失敗還是成功。

  按照包的方式通訊,就能在遠(yuǎn)程桌面中傳遞各種復(fù)雜的動(dòng)作,每個(gè)動(dòng)作都封裝成一個(gè)一個(gè)的數(shù)據(jù)包進(jìn)行傳輸。接收包和發(fā)送包分開獨(dú)立進(jìn)行,互相不干擾,每個(gè)包是否需要應(yīng)答包,根據(jù)每個(gè)包的需求決定,不是必須的。這又回到了 UDP通訊方式。那為何不干脆使用UDP代替呢? 還是上邊提到的原因,TCP保證穩(wěn)定和順序,這點(diǎn)在遠(yuǎn)程桌面等這類要求數(shù)據(jù)必須準(zhǔn)確的地方,是十分必要的。

  TCP如何保證傳輸?shù)氖菃为?dú)數(shù)據(jù)包?

  每個(gè)數(shù)據(jù)包定義成 ”包大小+包內(nèi)容“,比如4個(gè)字節(jié)表示包的大小,然后是包數(shù)據(jù)。

  發(fā)送的時(shí)候,“包大小+包內(nèi)容”組合到一起發(fā)送,接收的時(shí)候,先接收固定的4個(gè)字節(jié),獲取到包的size,

  然后再接收size字節(jié)的數(shù)據(jù),這樣一個(gè)包就接收完成。大致偽代碼如下:

  send_packet(tcp_socket, packet, packet_size) //發(fā)送數(shù)據(jù)包

  {

  int32 size = pakcet_size; ///應(yīng)該采用網(wǎng)絡(luò)序

  send(tcp_socket, &size, 4.。);

  send(tcp_socket, packet, packet_size);

  }

  recv_packet(tcp_socket)

  {

  int32 size;

  recv(tcp_socket, &size, 4,。。.);

  char* packet = malloc(size);

  recv( tcp_socket, packet, size, 。。.);

  return packet;

  }

非常好我支持^.^

(1) 100%

不好我反對(duì)

(0) 0%

( 發(fā)表人:姚遠(yuǎn)香 )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?