カテゴリ: Go言語 更新日: 2026/08/28

Go言語のTCP・UDPソケットプログラミング入門|初心者でもわかるネットワーク通信の基本

Go言語のTCP・UDPソケットプログラミング入門
Go言語のTCP・UDPソケットプログラミング入門

先生と生徒の会話形式で理解しよう

生徒

「Go言語で、パソコン同士が直接やり取りする通信ってできるんですか?」

先生

「できます。Go言語ではTCPやUDPという仕組みを使って、ネットワーク通信が行えます。」

生徒

「TCPとかUDPって、聞いたことはありますけど、何が違うんですか?」

先生

「それぞれ特徴があります。まずはソケット通信の基本から説明していきますね。」

1. ソケットプログラミングとは?

1. ソケットプログラミングとは?
1. ソケットプログラミングとは?

ソケットプログラミングとは、ネットワークを通じてデータを送ったり受け取ったりする仕組みを直接扱うプログラミング方法です。

とても難しく聞こえますが、イメージとしては「手紙の通り道」を自分で用意して、文字をやり取りする感じです。

Go言語はネットワーク処理が標準機能として充実しているため、TCPやUDPのソケット通信を比較的簡単に書けます。

2. TCP通信とUDP通信の違い

2. TCP通信とUDP通信の違い
2. TCP通信とUDP通信の違い

TCPは、確実にデータを届ける通信方法です。順番通りに届き、途中で失敗するとやり直します。Webサイト閲覧やメールで使われています。

UDPは、速さ重視の通信方法です。多少データが欠けても気にせず送ります。動画配信やゲーム通信でよく使われます。

Go言語では、用途に応じてTCPとUDPを使い分けることが大切です。

3. Go言語でTCPサーバーを作る基本

3. Go言語でTCPサーバーを作る基本
3. Go言語でTCPサーバーを作る基本

まずはTCP通信の受け口となるサーバーを作ってみましょう。これは「電話を受ける側」の役割です。


package main

import (
    "net"
)

func main() {
    listener, _ := net.Listen("tcp", ":8080")
    defer listener.Close()

    conn, _ := listener.Accept()
    defer conn.Close()
}

net.Listenは「この番号で待ちます」という意味です。ここでは8080番ポートで通信を待っています。

4. TCPでデータを送受信してみよう

4. TCPでデータを送受信してみよう
4. TCPでデータを送受信してみよう

次に、TCP通信で文字を受け取り、返す簡単な例です。これは「会話」をしている状態です。


buf := make([]byte, 1024)
conn.Read(buf)
conn.Write([]byte("受信しました"))

Readは相手の声を聞く操作、Writeは自分の声を送る操作だと考えると分かりやすいです。

5. Go言語でTCPクライアントを作る

5. Go言語でTCPクライアントを作る
5. Go言語でTCPクライアントを作る

次は、サーバーに接続するクライアント側の例です。こちらは「電話をかける側」です。


package main

import (
    "net"
)

func main() {
    conn, _ := net.Dial("tcp", "localhost:8080")
    defer conn.Close()

    conn.Write([]byte("こんにちは"))
}

Dialは「指定した相手に接続する」という意味です。TCP通信の基本形になります。

6. UDP通信の基本的な考え方

6. UDP通信の基本的な考え方
6. UDP通信の基本的な考え方

UDP通信は、TCPと違って接続という概念がありません。送るときに毎回相手を指定します。

その分、処理が軽く速いですが、確実性は保証されません。Go言語でもUDPはシンプルに扱えます。

7. Go言語でUDP通信を行う例

7. Go言語でUDP通信を行う例
7. Go言語でUDP通信を行う例

最後に、UDPでデータを送信する簡単な例です。これは「一方的に声を投げる」イメージです。


package main

import (
    "net"
)

func main() {
    addr, _ := net.ResolveUDPAddr("udp", "localhost:9000")
    conn, _ := net.DialUDP("udp", nil, addr)
    defer conn.Close()

    conn.Write([]byte("UDP通信"))
}

UDPでは、接続確認をせずにデータを送ります。そのため、リアルタイム性が高い処理に向いています。

まとめ

まとめ
まとめ

今回は、Go言語のTCP通信とUDP通信を中心に、ソケットプログラミングとネットワーク通信の基本を学びました。ソケットプログラミングとは、ネットワークを通じて別のパソコンやプログラムとデータを送受信するための仕組みを扱うプログラミングです。Go言語にはネットワーク処理に必要な機能が標準で用意されているため、TCPサーバーやTCPクライアント、UDP通信の基本を比較的短いコードで試すことができます。

ネットワーク通信という言葉を聞くと難しそうに感じますが、最初はサーバーとクライアントがデータをやり取りする仕組みとして考えると理解しやすくなります。サーバーは接続を待つ側、クライアントはサーバーへ接続する側です。TCP通信では、サーバーが待ち受ける場所を用意し、クライアントがそこへ接続して、文字列などのデータを送受信します。

TCPとUDPの違いを最初に理解しておこう

Go言語でネットワークプログラミングを学ぶうえで、最初に整理したいのがTCPとUDPの違いです。どちらもネットワーク上でデータをやり取りするための通信方法ですが、特徴が異なります。

TCPは、相手との接続を確立してからデータをやり取りする通信方法です。送信したデータを順番通りに届けることや、通信中に問題が起きた場合の再送などを重視するため、確実性を求める通信に向いています。記事では、Webサイトの閲覧やメールなどで利用される通信として紹介しました。

一方のUDPは、TCPのような接続を前提とせず、相手へデータを送る方式です。確実に届くことよりも、処理の軽さや速さを重視します。そのため、動画配信やゲーム通信など、多少のデータ欠損よりもリアルタイム性が重要な場面で使われます。

比較項目 TCP UDP
通信の考え方 接続してから通信する 接続を前提とせず送信する
特徴 確実性を重視する 速さを重視する
データの順序 順番通りに届けることを重視する 確実な順序を前提としない
向いている用途 Webやメールなど 動画やゲーム通信など

初心者のうちは、確実にデータをやり取りしたいならTCP、リアルタイム性や軽さを重視したいならUDPという大きな違いから覚えるとよいでしょう。

Go言語のTCPサーバーは接続を待つ側

TCP通信を理解するためには、サーバーとクライアントの役割を区別することが重要です。サーバーは、クライアントからの接続を待つ側です。電話に例えると、電話がかかってくるのを待っている側に近いイメージです。

Go言語では、net.Listenを利用してTCP通信の待ち受けを開始できます。待ち受けを始めるときには、どの通信方式を使うのかと、どのポート番号で待つのかを指定します。

package main

import (
    "fmt"
    "net"
)

func main() {
    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Println("待ち受け開始に失敗しました:", err)
        return
    }
    defer listener.Close()

    fmt.Println("TCPサーバーを開始しました")

    conn, err := listener.Accept()
    if err != nil {
        fmt.Println("接続受付に失敗しました:", err)
        return
    }
    defer conn.Close()

    fmt.Println("クライアントが接続しました")
}

このサンプルでは、8080番のポートでTCP通信を待っています。net.Listenで待ち受けを開始し、Acceptでクライアントからの接続を受け付けています。Go言語のTCPサーバーを学ぶときは、この待ち受け開始と接続受付の流れを最初に覚えることが大切です。

ポート番号は通信の窓口を表す

TCPサーバーのコードで登場したポート番号も、ネットワーク通信を理解するうえで重要です。パソコンでは複数のネットワークプログラムが同時に動くことがあります。そのため、どのプログラムに通信を届けるのかを区別するためにポート番号が使われます。

記事では8080番のポートを使いました。イメージとしては、一台の建物に複数の窓口があり、それぞれに番号が付いているようなものです。クライアントは接続先となるコンピュータだけではなく、その中のどの窓口へ接続するのかも指定します。

Go言語でTCPやUDPのソケット通信を扱うときには、IPアドレスやホスト名だけでなく、ポート番号も通信相手を決める重要な情報になります。

TCPクライアントはnet.Dialでサーバーへ接続する

サーバーが接続を待つ側なら、クライアントは接続を開始する側です。Go言語ではnet.Dialを使ってTCPサーバーへ接続できます。

記事では、同じパソコン上で動いているTCPサーバーへ接続するためにlocalhostを利用しました。localhostは、自分自身のコンピュータを表す名前として使われます。学習中は一台のパソコンでサーバーとクライアントを別々に動かせるため、TCP通信の練習に便利です。

package main

import (
    "fmt"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        fmt.Println("サーバーへの接続に失敗しました:", err)
        return
    }
    defer conn.Close()

    fmt.Println("サーバーへ接続しました")

    _, err = conn.Write([]byte("こんにちは"))
    if err != nil {
        fmt.Println("送信に失敗しました:", err)
        return
    }

    fmt.Println("データを送信しました")
}

このように、サーバー側で待ち受けを開始し、クライアント側から同じポート番号へ接続することでTCP通信の入り口が完成します。

ReadとWriteでTCPデータを送受信できる

接続ができたら、次に必要になるのがデータの送受信です。Go言語では、接続を表す値に対してReadを使えば受信し、Writeを使えば送信できます。

記事ではReadを相手の声を聞く操作、Writeを自分の声を送る操作として説明しました。ネットワーク通信ではデータをバイトの集まりとして扱うため、文字列を送信するときにもバイト列へ変換して送る形になります。

buf := make([]byte, 1024)

size, err := conn.Read(buf)
if err != nil {
    fmt.Println("受信に失敗しました:", err)
    return
}

message := string(buf[:size])
fmt.Println("受信内容:", message)

_, err = conn.Write([]byte("受信しました"))
if err != nil {
    fmt.Println("返信に失敗しました:", err)
}

受信するときには、受信データを入れるための領域を用意します。記事では千二十四バイト分の領域を用意していました。実際に何バイト受信したかを確認し、その範囲を文字列に変換することで、受け取ったメッセージを扱えます。

TCP通信ではサーバーとクライアントの両方が必要

TCPのソケットプログラミングを学ぶときは、サーバーだけを書いて終わりではありません。サーバーが接続を待ち、クライアントが接続し、クライアントから送信されたデータをサーバーが受信し、必要なら返信するという一連の流れを理解することが大切です。

TCP通信の基本的な流れ
  1. サーバーが指定したポート番号で待ち受けを開始する
  2. クライアントがサーバーへ接続する
  3. サーバーがクライアントからの接続を受け付ける
  4. クライアントがデータを送信する
  5. サーバーがデータを受信する
  6. 必要に応じてサーバーからクライアントへ返信する

この順番を一つずつ確認すると、TCPソケット通信の仕組みを整理しやすくなります。

deferを使って通信を最後に閉じる

記事のTCPサーバーやTCPクライアントでは、接続後にdeferとCloseを使っていました。ネットワーク接続は、使い終わったら閉じる必要があります。

deferを利用すると、現在の関数が終了するときに指定した処理を実行できます。そのため、接続を作ったあとにCloseを予約しておけば、処理終了時に通信を閉じる流れを作りやすくなります。

TCP通信だけでなくUDP通信でも、作成した接続を最後に閉じることが重要です。Go言語のネットワークプログラミングでは、接続を開始する処理と終了する処理をセットで意識するとよいでしょう。

UDPは接続を前提としない通信

UDP通信は、TCPとは通信の考え方が異なります。記事では、TCPには接続という考え方があり、UDPでは接続確認をせずにデータを送ると説明しました。

TCPではサーバーとクライアントが通信のつながりを作ってからデータをやり取りします。一方でUDPでは、データを送信するときに送り先を指定し、そこへデータを送るという考え方になります。

この違いによって、UDPはTCPよりも処理を軽くしやすく、リアルタイム性を重視する用途に向いています。ただし、送信したデータが必ず相手に届くことを前提にはできません。そのため、用途に応じてTCPとUDPを使い分ける必要があります。

Go言語のUDP通信では送信先のアドレスを指定する

Go言語でUDP通信を行う基本例では、まず送信先となるUDPアドレスを用意し、そのアドレスへデータを送信します。記事ではlocalhostの九千番ポートを送信先としていました。

package main

import (
    "fmt"
    "net"
)

func main() {
    addr, err := net.ResolveUDPAddr("udp", "localhost:9000")
    if err != nil {
        fmt.Println("UDPアドレスの取得に失敗しました:", err)
        return
    }

    conn, err := net.DialUDP("udp", nil, addr)
    if err != nil {
        fmt.Println("UDP通信の準備に失敗しました:", err)
        return
    }
    defer conn.Close()

    _, err = conn.Write([]byte("UDP通信"))
    if err != nil {
        fmt.Println("UDP送信に失敗しました:", err)
        return
    }

    fmt.Println("UDPデータを送信しました")
}

このように、UDPでもGo言語のnetパッケージを使って通信処理を記述できます。TCPと同じネットワーク通信でも、使用する関数や通信の考え方が異なる点を比較しながら覚えると理解しやすくなります。

Go言語のnetパッケージがネットワーク通信の基本になる

今回の記事で登場したTCPサーバー、TCPクライアント、UDP通信では、いずれもGo言語のnetパッケージを利用しています。

Go言語はネットワーク処理に必要な標準機能が充実しており、外部の特別なライブラリを用意しなくてもTCPやUDPの基本的なソケットプログラミングを学べます。net.Listen、net.Dial、net.ResolveUDPAddr、net.DialUDPなど、それぞれの役割を理解していくことがネットワークプログラミングの第一歩です。

機能 主な役割
net.Listen TCPサーバーで接続を待ち受ける
Accept クライアントからの接続を受け付ける
net.Dial TCPサーバーへ接続する
Read 通信相手からデータを受信する
Write 通信相手へデータを送信する
net.ResolveUDPAddr UDPの送信先アドレスを用意する
net.DialUDP UDP通信を行うための準備をする

実際のプログラムではエラー処理も重要

記事内の短いサンプルでは、TCPやUDPの仕組みを分かりやすくするため、エラー処理を簡略化している箇所がありました。しかし実際のGo言語プログラムでは、ネットワーク処理のエラーを確認することが非常に重要です。

例えば、指定したポートを使えない場合、サーバーが起動していない場合、接続に失敗した場合、データの送信や受信に失敗した場合など、ネットワーク通信ではさまざまな理由で処理が失敗する可能性があります。

Go言語では多くのネットワーク関数がエラー情報を返すため、その値を確認して問題があれば適切なメッセージを表示したり、処理を終了したりすることが大切です。TCPやUDPの基本を理解したら、次はエラー処理を含めた安全な通信プログラムを意識するとよいでしょう。

TCPとUDPは用途によって選ぶことが大切

TCPとUDPにはそれぞれ長所があります。そのため、どちらか一方が常に優れているというわけではありません。通信するデータの性質によって選択することが重要です。

送信した情報をできるだけ確実に相手へ届けたい場合はTCPが適しています。例えば、文章や重要なデータを途中で失いたくない通信では、確実性が重要になります。

一方、多少のデータ欠損よりも遅延を少なくしたい場合はUDPが候補になります。記事で紹介した動画配信やゲーム通信のように、現在の情報を素早く送り続けることが重要な処理では、UDPの特徴を活かせます。

TCPは確実性を重視し、UDPは速さやリアルタイム性を重視するという基本を覚えておくと、通信方式を選びやすくなります。

localhostを使えば一台のパソコンでも通信を練習できる

ソケットプログラミングというと複数台のパソコンが必要に思えるかもしれませんが、記事で紹介したようにlocalhostを使えば、自分のパソコンの中でサーバーとクライアントを動かして練習できます。

例えば最初にTCPサーバーを起動して8080番ポートで待ち受け、そのあと別のプログラムとしてTCPクライアントを実行してlocalhostの8080番ポートへ接続します。これだけでも、接続、送信、受信というネットワーク通信の基本的な流れを確認できます。

Go言語初心者がTCPやUDPを学習するときは、最初から複雑なネットワーク環境を用意するよりも、自分のパソコン内で短い文字列を送る練習から始めると理解しやすくなります。

初心者はTCP通信から練習すると流れを理解しやすい

ネットワークプログラミングを初めて学ぶ場合は、まずTCPサーバーとTCPクライアントを作って通信の流れを確認すると分かりやすいでしょう。

サーバーで待つ、クライアントから接続する、文字列を送る、サーバーが受け取る、サーバーから返信するという順番を実際に動かすと、ソケット通信という言葉の意味を具体的に理解できます。

TCP通信の基本が理解できたら、次にUDPの送信を試し、接続を前提とするTCPと、接続を前提としないUDPの違いを比べると理解が深まります。

Go言語のTCPとUDPで覚えておきたい基本ポイント
  • ソケットプログラミングはネットワーク上でデータを送受信する仕組みを扱う
  • TCPは接続してからデータをやり取りする
  • TCPは確実性を重視する通信に向いている
  • UDPは接続を前提とせずデータを送る
  • UDPは速さやリアルタイム性を重視する通信に向いている
  • TCPサーバーはnet.Listenで待ち受けを開始する
  • Acceptでクライアントからの接続を受け付ける
  • TCPクライアントはnet.Dialでサーバーへ接続する
  • Readでデータを受信しWriteでデータを送信する
  • UDPでは送信先となるアドレスを指定する
  • ポート番号は通信するプログラムの窓口を区別する
  • ネットワーク処理ではエラー確認と接続の終了処理も重要になる

Go言語のネットワーク通信は小さなサンプルから理解しよう

Go言語のTCP通信やUDP通信は、最初は専門用語が多く難しく感じるかもしれません。しかし、一つずつ役割を整理すると、それほど複雑ではありません。サーバーは待つ側、クライアントは接続する側、Readは受信、Writeは送信という基本を覚えるだけでも、サンプルコードを読みやすくなります。

さらに、TCPは確実性を重視する通信、UDPはリアルタイム性を重視する通信として比較すると、それぞれの役割を整理できます。実際に短いメッセージを一つ送ってみるだけでも、ネットワーク通信がどのように成立しているのかを実感できます。

Go言語にはnetパッケージが用意されているため、ソケットプログラミングの基本を標準機能だけで学習できます。まずTCPサーバーとTCPクライアントをlocalhostで動かし、そのあとUDP送信を試すという順番で練習すると、ネットワーク通信の基礎を段階的に身につけられます。

TCPやUDPの基礎を理解できると、Web通信やゲーム通信、リアルタイム通信など、普段利用しているさまざまなネットワークサービスの仕組みを理解する土台にもなります。Go言語でネットワークプログラミングを学ぶときは、通信方式の名前だけを暗記するのではなく、どのように接続し、どのようにデータを送受信するのかを実際のコードと結びつけて理解することが大切です。

先生と生徒の振り返り会話

生徒

「最初はTCPやUDPって難しそうでしたけど、どちらもネットワークでデータを送るための方法なんですね。」

先生

「そうです。ただし通信の考え方が違います。TCPは接続してから確実性を重視して通信し、UDPは接続を前提とせず速さを重視して送信します。」

生徒

「TCPサーバーは、まずポート番号を決めてクライアントからの接続を待つんですよね。」

先生

「そのとおりです。Go言語ではnet.Listenを使って待ち受けを開始し、Acceptでクライアントの接続を受け付けます。」

生徒

「クライアント側はnet.Dialでサーバーへ接続するんでしたね。」

先生

「はい。接続ができたら、Writeで送信してReadで受信できます。まずは短い文字列を送って確認すると分かりやすいですよ。」

生徒

「localhostを使えば、自分のパソコンだけでもサーバーとクライアントの通信を試せるんですね。」

先生

「その方法が初心者にはおすすめです。サーバーを起動したあと、別のクライアントプログラムから同じポートへ接続してみましょう。」

生徒

「UDPの場合はTCPみたいに接続を待ってから送るという考え方ではないんですよね。」

先生

「はい。UDPは送り先を指定してデータを送ります。確実に届くことよりも、軽さやリアルタイム性を重視する通信です。」

生徒

「だからWebやメールのように確実性が大切ならTCP、ゲームや動画のように速さが大切な処理ではUDPが使われることがあるんですね。」

先生

「その違いを理解できれば、TCPとUDPの基本はかなり整理できています。」

生徒

「記事の短いコードではエラー処理を省いているところもありましたが、実際のプログラムでは確認したほうがいいんですよね。」

先生

「もちろんです。接続できない、ポートを使えない、送信や受信に失敗するといったことがあるので、実際の開発ではエラー処理が重要です。」

生徒

「まずはTCPサーバーとTCPクライアントを作って、文字列を一つ送るところから試してみます。」

先生

「それがよいですね。そのあとサーバーから返信する処理やUDP通信も試していけば、Go言語のソケットプログラミングとネットワーク通信の基本がしっかり身についていきますよ。」

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Go言語のソケットプログラミングとは何ですか?プログラミング初心者でも理解できますか?

Go言語のソケットプログラミングとは、ネットワークを通じてパソコン同士やプログラム同士でデータを送受信する仕組みを扱うプログラミング方法です。難しく感じるかもしれませんが、データを届けるための通り道を用意して、そこを使って文字などの情報をやり取りすると考えると理解しやすくなります。Go言語にはネットワーク通信を扱うための標準機能が用意されているため、初心者でも基本から順番に学習できます。
関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアやクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

カテゴリの一覧へ
新着記事
New1
Kotlin
Kotlinのrunの使い方!スコープ内で処理をまとめるテクニック
New2
Kotlin
Kotlinの文字列を逆順にするreversedの使い方を徹底解説!初心者でもわかる文字列操作入門
New3
Kotlin
KotlinのtoList・toCharArrayの使い方を徹底解説!文字列をリストに変換する方法を初心者向けにやさしく説明
New4
Kotlin
Kotlinの拡張プロパティとは?基本的な作り方と活用例を初心者向けに解説
人気記事
No.1
Java&Spring記事人気No1
C#
C#プログラムの基本的な書き方を完全解説!初心者でもわかる文法入門ガイド
No.2
Java&Spring記事人気No2
Swift
Swift入門ガイド|基本構文と書き方をマスターしよう
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.5
Java&Spring記事人気No5
Kotlin
Kotlinのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.6
Java&Spring記事人気No6
Kotlin
KotlinでZIPファイルの圧縮と解凍を実装する手順を完全解説!Kotlinファイル操作と入出力I/O入門
No.7
Java&Spring記事人気No7
C#
C#の論理演算子の使い方を完全ガイド!&&・||・!を初心者でもわかりやすく解説
No.8
Java&Spring記事人気No8
TypeScript
TypeScriptのLiteral型とは?基本・特徴を初心者向けにわかりやすく解説

💻 作業効率アップに

ノートPCを縦置きしてデスクを広く。
省スペースで片づく定番スタンド

UGREEN 縦型スタンドをAmazonで見る

※ Amazon広告リンク