<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

鴻蒙開發實戰:【網絡管理-Socket連接】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-03-19 22:04 ? 次閱讀

介紹

本示例主要演示了Socket在網絡通信方面的應用,展示了Socket在兩端設備的連接驗證、聊天通信方面的應用。

效果預覽

image.png

使用說明

1.打開應用,點擊用戶文本框選擇要登錄的用戶,并輸入另一個設備的IP地址,點擊確定按鈕進入已登錄的用戶頁面(兩個設備都要依次執行此步驟)。

2.在其中一個設備上點擊創建房間按鈕,任意輸入房間號,另一個設備會收到有房間號信息的彈框,點擊確定按鈕后,兩個設備進入聊天頁面。

3.在其中一個設備上輸入聊天信息并點擊發送按鈕后,另一個設備的聊天頁面會收到該聊天消息。

4.點擊頂部標題欄右側的退出圖標按鈕,則返回已登錄的用戶頁面。

5.點擊聊天頁面中的昵稱欄,會彈出一個菜單,選擇離線選項后,兩端設備的狀態圖標都會切換為離線圖標,并且昵稱欄都會變成灰色,此時任何一端發送消息另一端都接收不到消息。

6.當點擊昵稱欄再次切換為在線狀態,則兩端的己方賬號狀態會切換為在線圖標,同時兩端的昵稱欄會顯示藍色,此時可正常收發消息。

工程目錄

entry/src/main/ets/MainAbility
|---app.ets
|---model
|   |---chatBox.ts                     // 聊天頁面
|   |---DataSource.ts                  // 數據獲取
|   |---Logger.ts                      // 日志工具
|---pages
|   |---Index.ets                      // 監聽消息頁面
|   |---Login.ets                      // 首頁登錄頁面
|---Utils
|   |---Utils.ets

具體實現

  • 本示例分為三個模塊
    • 輸入對端IP模塊
      • 使用wifi.getIpInfo()方法獲取IP地址,constructUDPSocketInstance方法創建一個UDPSocket對象
      • 源碼鏈接:[Login.ets]
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import wifi from '@ohos.wifi';
import router from '@ohos.router';
import { resolveIP } from '../Utils/Util'
import socket from '@ohos.net.socket';
import Logger from '../model/Logger'

const TAG: string = '[Login]'

let localAddr = {
  address: resolveIP(wifi.getIpInfo().ipAddress),
  family: 1,
  port: 0
}
let oppositeAddr = {
  address: '',
  family: 1,
  port: 0
}
let loginCount = 0

let udp = socket.constructUDPSocketInstance()

@Entry
@Component
struct Login {
  @State login_feng: boolean = false
  @State login_wen: boolean = false
  @State user: string = ''
  @State roomDialog: boolean = false
  @State confirmDialog: boolean = false
  @State ipDialog: boolean = true
  @State warnDialog: boolean = false
  @State warnText: string = ''
  @State roomNumber: string = ''
  @State receiveMsg: string = ''

  bindOption() {
    let bindOption = udp.bind(localAddr);
    bindOption.then(() = > {
      Logger.info(TAG, 'bind success');
    }).catch(err = > {
      Logger.info(TAG, 'bind fail');
    })
    udp.on('message', data = > {
      Logger.info(TAG, `data:${JSON.stringify(data)}`);
      let buffer = data.message;
      let dataView = new DataView(buffer);
      Logger.info(TAG, `length = ${dataView.byteLength}`);
      let str = '';
      for (let i = 0;i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i));
        if (c != '') {
          str += c;
        }
      }
      if (str == 'ok') {
        router.clear();
        loginCount += 1;
        router.push({
          url: 'pages/Index',
          params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
        })
      }
      else {
        this.receiveMsg = str;
        this.confirmDialog = true;
      }
    })
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      Column() {
        Text($r('app.string.MainAbility_label'))
          .width('100%')
          .height(50)
          .backgroundColor('#0D9FFB')
          .textAlign(TextAlign.Start)
          .fontSize(25)
          .padding({ left: 10 })
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bold)
        if (!this.ipDialog) {
          Column() {
            Image(this.login_feng ? $r('app.media.fengziOn') : $r('app.media.wenziOn'))
              .width(100)
              .height(100)
              .objectFit(ImageFit.Fill)
            Text('用戶名:' + this.user).fontSize(25).margin({ top: 50 })

            Button() {
              Text($r('app.string.create_room')).fontSize(25).fontColor(Color.White)
            }
            .width('150')
            .height(50)
            .margin({ top: 30 })
            .type(ButtonType.Capsule)
            .onClick(() = > {
              this.roomDialog = true
              this.bindOption()
            })
          }.width('90%').margin({ top: 100 })
        }

      }.width('100%').height('100%')

      if (this.confirmDialog) {
        Column() {
          Text('確認碼:' + this.receiveMsg).fontSize(25)
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() = > {
                this.confirmDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() = > {
                udp.send({
                  data: 'ok',
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send ${JSON.stringify(err)}`);
                })
                router.clear()
                loginCount += 1;
                router.push({
                  url: 'pages/Index',
                  params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
                })
                this.confirmDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.ipDialog) {
        Column() {
          Text('本地IP:' + localAddr.address).fontSize(25).margin({ top: 10 })
          Text('用戶:' + this.user).fontSize(20).margin({ top: 10 })
            .bindMenu([{
              value: '風子',
              action: () = > {
                this.user = '風子'
                this.login_feng = true
                this.login_wen = false
                localAddr.port = 8080
                oppositeAddr.port = 9090
              }
            },
              {
                value: '蚊子',
                action: () = > {
                  this.user = '蚊子'
                  this.login_wen = true
                  this.login_feng = false
                  localAddr.port = 9090
                  oppositeAddr.port = 8080
                }
              }
            ])
          TextInput({ placeholder: '請輸入對端ip' })
            .width(200)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) = > {
              oppositeAddr.address = value;
            })

          if (this.warnDialog) {
            Text(this.warnText).fontSize(10).fontColor(Color.Red).margin({ top: 5 })
          }
          Button($r('app.string.confirm'))
            .fontColor(Color.Black)
            .height(30)
            .margin({ bottom: 10 })
            .onClick(() = > {
              if (this.user == '') {
                this.warnDialog = true;
                this.warnText = '請先選擇用戶';
              } else if (oppositeAddr.address === '') {
                this.warnDialog = true;
                this.warnText = '請先輸入對端IP';
              } else {
                this.bindOption()
                this.ipDialog = false;
                Logger.debug(TAG, `peer ip=${oppositeAddr.address}`);
                Logger.debug(TAG, `peer port=${oppositeAddr.port}`);
                Logger.debug(TAG, `peer port=${localAddr.port}`);
              }
            })
            .backgroundColor(0xffffff)
        }
        .width('80%')
        .height(200)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.roomDialog) {
        Column() {
          Text($r('app.string.input_roomNumber')).fontSize(25).margin({ top: 10 })
          TextInput()
            .width(100)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) = > {
              this.roomNumber = value;
            })
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() = > {
                this.roomDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() = > {
                Logger.info(TAG, `[ROOM]address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]port=${oppositeAddr.port}`);
                /*點擊確定后發送房間號,另一端開始監聽*/
                Logger.info(TAG, `[ROOM]oppositeAddr.address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]oppositeAddr.port=${oppositeAddr.port}`);
                Logger.info(TAG, `[ROOM]localAddr.address=${localAddr.address}`);
                Logger.info(TAG, `[ROOM]localAddr.port=${localAddr.port}`);
                this.bindOption()
                udp.send({
                  data: this.roomNumber,
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send success, data = ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send fail, err = ${JSON.stringify(err)}`);
                })
                this.roomDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
    }
  }
}

[Util.ets]

/*

* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
  */

export function resolveIP(ip) {
if (ip < 0 || ip > 0xFFFFFFFF) {
throw ('The number is not normal!');
}
return (ip > >> 24) + '.' + (ip > > 16 & 0xFF) + '.' + (ip > > 8 & 0xFF) + '.' + (ip & 0xFF);
}
  • 創建房間模塊
    • 點擊創建房間按鈕,彈出創建房間框,輸入房間號,點擊確定,進入聊天頁面
    • 源碼鏈接:[Login.ets]
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import wifi from '@ohos.wifi';
import router from '@ohos.router';
import { resolveIP } from '../Utils/Util'
import socket from '@ohos.net.socket';
import Logger from '../model/Logger'

const TAG: string = '[Login]'

let localAddr = {
  address: resolveIP(wifi.getIpInfo().ipAddress),
  family: 1,
  port: 0
}
let oppositeAddr = {
  address: '',
  family: 1,
  port: 0
}
let loginCount = 0

let udp = socket.constructUDPSocketInstance()

@Entry
@Component
struct Login {
  @State login_feng: boolean = false
  @State login_wen: boolean = false
  @State user: string = ''
  @State roomDialog: boolean = false
  @State confirmDialog: boolean = false
  @State ipDialog: boolean = true
  @State warnDialog: boolean = false
  @State warnText: string = ''
  @State roomNumber: string = ''
  @State receiveMsg: string = ''

  bindOption() {
    let bindOption = udp.bind(localAddr);
    bindOption.then(() = > {
      Logger.info(TAG, 'bind success');
    }).catch(err = > {
      Logger.info(TAG, 'bind fail');
    })
    udp.on('message', data = > {
      Logger.info(TAG, `data:${JSON.stringify(data)}`);
      let buffer = data.message;
      let dataView = new DataView(buffer);
      Logger.info(TAG, `length = ${dataView.byteLength}`);
      let str = '';
      for (let i = 0;i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i));
        if (c != '') {
          str += c;
        }
      }
      if (str == 'ok') {
        router.clear();
        loginCount += 1;
        router.push({
          url: 'pages/Index',
          params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
        })
      }
      else {
        this.receiveMsg = str;
        this.confirmDialog = true;
      }
    })
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      Column() {
        Text($r('app.string.MainAbility_label'))
          .width('100%')
          .height(50)
          .backgroundColor('#0D9FFB')
          .textAlign(TextAlign.Start)
          .fontSize(25)
          .padding({ left: 10 })
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bold)
        if (!this.ipDialog) {
          Column() {
            Image(this.login_feng ? $r('app.media.fengziOn') : $r('app.media.wenziOn'))
              .width(100)
              .height(100)
              .objectFit(ImageFit.Fill)
            Text('用戶名:' + this.user).fontSize(25).margin({ top: 50 })

            Button() {
              Text($r('app.string.create_room')).fontSize(25).fontColor(Color.White)
            }
            .width('150')
            .height(50)
            .margin({ top: 30 })
            .type(ButtonType.Capsule)
            .onClick(() = > {
              this.roomDialog = true
              this.bindOption()
            })
          }.width('90%').margin({ top: 100 })
        }

      }.width('100%').height('100%')

      if (this.confirmDialog) {
        Column() {
          Text('確認碼:' + this.receiveMsg).fontSize(25)
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() = > {
                this.confirmDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() = > {
                udp.send({
                  data: 'ok',
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send ${JSON.stringify(err)}`);
                })
                router.clear()
                loginCount += 1;
                router.push({
                  url: 'pages/Index',
                  params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
                })
                this.confirmDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.ipDialog) {
        Column() {
          Text('本地IP:' + localAddr.address).fontSize(25).margin({ top: 10 })
          Text('用戶:' + this.user).fontSize(20).margin({ top: 10 })
            .bindMenu([{
              value: '風子',
              action: () = > {
                this.user = '風子'
                this.login_feng = true
                this.login_wen = false
                localAddr.port = 8080
                oppositeAddr.port = 9090
              }
            },
              {
                value: '蚊子',
                action: () = > {
                  this.user = '蚊子'
                  this.login_wen = true
                  this.login_feng = false
                  localAddr.port = 9090
                  oppositeAddr.port = 8080
                }
              }
            ])
          TextInput({ placeholder: '請輸入對端ip' })
            .width(200)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) = > {
              oppositeAddr.address = value;
            })

          if (this.warnDialog) {
            Text(this.warnText).fontSize(10).fontColor(Color.Red).margin({ top: 5 })
          }
          Button($r('app.string.confirm'))
            .fontColor(Color.Black)
            .height(30)
            .margin({ bottom: 10 })
            .onClick(() = > {
              if (this.user == '') {
                this.warnDialog = true;
                this.warnText = '請先選擇用戶';
              } else if (oppositeAddr.address === '') {
                this.warnDialog = true;
                this.warnText = '請先輸入對端IP';
              } else {
                this.bindOption()
                this.ipDialog = false;
                Logger.debug(TAG, `peer ip=${oppositeAddr.address}`);
                Logger.debug(TAG, `peer port=${oppositeAddr.port}`);
                Logger.debug(TAG, `peer port=${localAddr.port}`);
              }
            })
            .backgroundColor(0xffffff)
        }
        .width('80%')
        .height(200)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.roomDialog) {
        Column() {
          Text($r('app.string.input_roomNumber')).fontSize(25).margin({ top: 10 })
          TextInput()
            .width(100)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) = > {
              this.roomNumber = value;
            })
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() = > {
                this.roomDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() = > {
                Logger.info(TAG, `[ROOM]address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]port=${oppositeAddr.port}`);
                /*點擊確定后發送房間號,另一端開始監聽*/
                Logger.info(TAG, `[ROOM]oppositeAddr.address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]oppositeAddr.port=${oppositeAddr.port}`);
                Logger.info(TAG, `[ROOM]localAddr.address=${localAddr.address}`);
                Logger.info(TAG, `[ROOM]localAddr.port=${localAddr.port}`);
                this.bindOption()
                udp.send({
                  data: this.roomNumber,
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send success, data = ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send fail, err = ${JSON.stringify(err)}`);
                })
                this.roomDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
    }
  }
}

[Util.ets]

/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

export function resolveIP(ip) {
  if (ip < 0 || ip > 0xFFFFFFFF) {
    throw ('The number is not normal!');
  }
  return (ip > >> 24) + '.' + (ip > > 16 & 0xFF) + '.' + (ip > > 8 & 0xFF) + '.' + (ip & 0xFF);
}

相關概念

UDP Socket是面向非連接的協議,它不與對方建立連接,而是直接把我要發的數據報發給對方,適用于一次傳輸數據量很少、對可靠性要求不高的或對實時性要求高的應用場景。

相關權限

1.允許使用Internet網絡權限:[ohos.permission.INTERNET]

2.允許應用獲取WLAN信息權限:[ohos.permission.GET_WIFI_INFO]

依賴

不涉及。

約束與限制

1.本示例僅支持標準系統上運行,支持設備:RK3568。

2.本示例僅支持API9版本SDK,版本號:3.2.11.9 及以上。

3.本示例需要使用DevEco Studio 3.1 Beta2 (Build Version: 3.1.0.400 構建 2023年4月7日)及以上才可編譯運行。

下載

如需單獨下載本工程,執行如下命令:

git init
git config core.sparsecheckout true
echo codeBasicFeatureConnectivitySocket > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Socket
    +關注

    關注

    0

    文章

    178

    瀏覽量

    34469
  • 網絡通信
    +關注

    關注

    4

    文章

    737

    瀏覽量

    29590
  • 鴻蒙
    +關注

    關注

    55

    文章

    1930

    瀏覽量

    42203
收藏 人收藏

    評論

    相關推薦

    HarmonyOS 網絡管理開發Socket 連接

    簡介 Socket 連接主要是通過 Socket 進行數據傳輸,支持 TCP/UDP/TLS 協議。 基本概念 ? ● Socket:套接字,就是對
    的頭像 發表于 02-18 09:20 ?581次閱讀

    鴻蒙實戰項目開發:【短信服務】

    環境搭建 ? 《鴻蒙開發基礎》 ArkTS語言 安裝DevEco Studio 運用你的第一個ArkTS應用 ArkUI聲明式UI開發 .…… ? 《鴻蒙
    發表于 03-03 21:29

    鴻蒙原生應用開發-網絡管理Socket連接(一)

    一、簡介 Socket連接主要是通過Socket進行數據傳輸,支持TCP/UDP/TLS協議。 二、基本概念 Socket:套接字,就是對網絡
    發表于 04-01 14:20

    鴻蒙原生應用開發-網絡管理Socket連接(二)

    應用TCP/UDP協議進行通信 1.UDP與TCP流程大體類似,下面以TCP為例: 2.import需要的socket模塊。 3.創建一個TCPSocket連接,返回一個TCPSocket對象
    發表于 04-02 15:22

    鴻蒙原生應用開發-網絡管理Socket連接(三)

    應用通過TLS Socket進行加密數據傳輸 開發步驟 客戶端TLS Socket流程: 1.import需要的socket模塊。 2.綁定服務器IP和端口號。 3.雙向認證上傳客戶端
    發表于 04-03 14:26

    鴻蒙原生應用開發-網絡管理模塊總述

    一、網絡管理模塊主要提供以下功能: HTTP數據請求:通過HTTP發起一個數據請求。 WebSocket連接:使用WebSocket建立服務器與客戶端的雙向連接。
    發表于 04-08 09:45

    實戰Linux Socket編程

    實戰Linux Socket編程
    發表于 03-03 10:17

    【中秋國慶不斷更】HarmonyOS網絡管理開發Socket連接

    簡介 Socket連接主要是通過Socket進行數據傳輸,支持TCP/UDP/TLS協議。 基本概念 ● Socket:套接字,就是對網絡
    發表于 09-27 15:44

    什么是Socket連接?Socket與TCP連接的關系

    主機 A 的應用程序必須通過 Socket 建立連接才能與主機B的應用程序通信,而建立 Socket 連接需要底層 TCP/IP 協議來建立 TCP
    發表于 03-31 15:10 ?822次閱讀

    什么是Socket連接?與TCP連接有什么關系?

    什么是Socket連接?它與TCP連接有什么關系? 計算機網絡是我們日常生活中不可或缺的一部分,而Socket
    的頭像 發表于 05-23 11:43 ?474次閱讀

    什么是Socket連接?它與TCP連接有什么關系?

    計算機網絡是我們日常生活中不可或缺的一部分,而Socket連接則是網絡通信中必不可少的一種機制。在本篇文章中,我們將通過簡單易懂、生動形象的語言,向大家介紹
    的頭像 發表于 03-06 11:00 ?902次閱讀
    什么是<b class='flag-5'>Socket</b><b class='flag-5'>連接</b>?它與TCP<b class='flag-5'>連接</b>有什么關系?

    【干貨】什么是Socket連接?它與TCP連接有什么關系?

    計算機網絡是我們日常生活中不可或缺的一部分,而Socket連接則是網絡通信中必不可少的一種機制。在本篇文章中,我們將通過簡單易懂、生動形象的語言,向大家介紹
    的頭像 發表于 04-09 10:39 ?898次閱讀
    【干貨】什么是<b class='flag-5'>Socket</b><b class='flag-5'>連接</b>?它與TCP<b class='flag-5'>連接</b>有什么關系?

    Socket 網絡編程框架介紹

    Socket 網絡編程框架 Socket(套接字)是一個網絡編程概念,描述了一個通信端點(Endpoint),用于建立網絡連接(Connec
    的頭像 發表于 11-09 14:19 ?434次閱讀
    <b class='flag-5'>Socket</b> <b class='flag-5'>網絡</b>編程框架介紹

    什么是Socket連接?Socket的工作原理 它與TCP連接有什么關系?

    和服務器之間的數據交換。 Socket連接的工作原理是基于TCP/IP協議。TCP(傳輸控制協議)是一種面向連接的、可靠的傳輸協議,用于在網絡中的兩個應用程序之間建立可靠的通信。而
    的頭像 發表于 01-22 16:10 ?675次閱讀

    鴻蒙OS開發實戰:【Socket小試MQTT連接

    本篇分享一下 HarmonyOS 中的Socket使用方法 將從2個方面實踐: 1. HarmonyOS 手機應用連接PC端 SocketServer 1. HarmonyOS 手機應用連接MQTT 服務端
    的頭像 發表于 04-01 16:14 ?495次閱讀
    <b class='flag-5'>鴻蒙</b>OS<b class='flag-5'>開發</b><b class='flag-5'>實戰</b>:【<b class='flag-5'>Socket</b>小試MQTT<b class='flag-5'>連接</b>】
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>