Go言語 初心者のための7つのチュートリアル VI ネットワーク・プログラミング
1. ソケットプログラミング
Goでネットワークプログラムを書く場合、従来のようなコーディングの形式は見られません。以前は、ソケットを使ったプログラミングをする場合、以下のような手順で行っていました。
ソケットを作成する。
socket()
関数を使用します。
ソケットをバインドする
bind()
関数を使用します。
リスニング:使用する
listen()
関数を使用します。または、接続する場合は
connect()
関数を使用します。
コネクションを受け付ける
accept()
関数を使用します。
受信する。を使用します。
receive()
関数を使用します。または、送信: を使用します。
send()
関数を使用します。
Go言語標準ライブラリは、この手続きを抽象化し、カプセル化しています。どのようなプロトコルを使ってどのような形式の接続を確立するかにかかわらず、必要なのは
net.Dial()
を実行すればOKです。
1.1 Dial() 関数
Dial()関数のプロトタイプは以下のとおりである。
func Dial(net, addr string) (Conn, error)
ここで
net
パラメータはネットワークプロトコルの名前です。
addr
パラメータは
IP
アドレスまたはドメイン名で始まり、ポート番号は
:
の後に、アドレスまたはドメイン名が続き、ポート番号は任意である。接続に成功した場合は接続オブジェクトが返され、そうでない場合は
error
.
一般的なプロトコルの呼び出しをいくつか見てみましょう。
TCP
リンクです。
conn, err := net.Dial("tcp", "192.168.1.8:3000")
UDP
リンク
conn, err := net.Dial("udp", "192.168.1.12:975")
ICMP
リンク(プロトコル名使用)。
conn, err := net.Dial("ip4:icmp", "www.baidu.com")
ICMP
リンク(プロトコル番号使用)。
conn, err := net.Dial("ip4:1", "10.0.0.3")
接続が正常に確立されたら、データの送受信を行うことができます。データを送信するには
conn
の
Write()
を使用してデータを受け取るメンバーメソッドです。
Read()
メソッドで受信します。
2. HTTP プログラミング
2.1 HTTPクライアント
Goの組み込み
net/http
パッケージは、最も簡潔な
HTTP
クライアントを実装しているので、サードパーティのネットワーク通信ライブラリ (例えば
libcurl
を使用することで、最もよく使われる HTTP
GET
と
POST
メソッドを使用してデータを要求します。
基本的なメソッド
net/http
パッケージ
Client
型は、いくつかのメソッドを提供し、それを使って
HTTP
のリクエストに対応します。
func (c *Client) Get(url string) (r *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)
その方法の概要は以下のとおりです。
- http.Get()
リソースを要求するには、以下のサンプルコードでhttp.Get()メソッド(http.DefaultClient.Get()と同等)を呼び出すだけです。
resp, err := http.Get("http://example.com/")
if err ! = nil { // Handle the error ...
return
}
defer resp.Body.close()
io.Copy(os.Stdout, resp.Body)
上記のコードは、ウェブサイトのホームページを要求し、そのページ内容を標準出力ストリームにプリントしています。
- http.Post()
で始めるには
POST
を呼び出すだけです。
http.Post()
メソッドに次の3つのパラメータを順番に渡してください。
要求された送信先URLは、POSTデータのビットストリーム([]byte形式)のリソースタイプ(MIMEType)になります。
次のサンプルコードは、画像をアップロードする方法を示しています。
resp, err := http.Post("http://example.com/upload", "image/jpeg", &imageDataBuf)
if err ! = nil{ // Handle the error
return
}
if resp.StatusCode ! = http.StatusOK {// Handle the error
return
}
- http.PostForm()
http.PostForm()
メソッドは、標準的なエンコーディング形式を
application/x-www-form-urlencoded
は、フォーム送信用です。次のサンプルコードは、新しい記事のためのHTMLフォーム送信をシミュレートしたものです。
resp, err := http.PostForm("http://example.com/posts", url.Values{"title":
{"article title"}, "content": {"article body"}})
if err ! = nil{ // Handle the error
return
}
- http.Head()
HTTPのHeadリクエストメソッドは、ターゲットURLのヘッダー情報であるHTTPヘッダーを返さずに、ヘッダーのみを要求することを示します。
Goの組み込みの
net/http
パッケージも提供します。
http.Head()
メソッドと同じです。
http.Get()
メソッドと同じです。
パラメータとしてターゲットURLを渡すだけです。次のコード例では、ウェブサイトのトップページのHTTPヘッダー情報を要求します。
resp, err := http.Head("http://baidu.com/")
- (*http.Client).Do()
ほとんどの場合
http.Get()
と
http.PostForm()
を起動すれば十分なのですが、もし
HTTPリクエストはよりカスタマイズされた情報を必要とするため、以下のようなカスタムHttpヘッダーフィールドを設定したい。
- User-Agent" をカスタムで設定します。
- クッキーの受け渡し
この時点では
net/http
パッケージ
http.Client
オブジェクトを作成します。
Do()
メソッドを実装しています。
req, err := http.NewRequest("GET", "http://baidu.com", nil)
// ...
req.Header.Add("User-Agent", "Gobook Custom User-Agent")
// ...
client := &http.Client{ // ... }
resp, err := client.Do(req)
2.2 HTTPサーバーサイド
2.2.1 HTTPリクエストの処理
を使用することで
net/http
パッケージによって提供されます。
http.ListenAndServe()
メソッドは、指定されたアドレスでリッスンし、HTTPをオープンします。このメソッドのサーバー側のプロトタイプは次のとおりです。
func ListenAndServe(addr string, handler Handler) error
このメソッドは、指定された
TCP
ネットワークアドレス
addr
をリッスンし、サーバー側のハンドラを呼び出して着信した接続要求を処理します。このメソッドには2つのパラメータがあります:最初のパラメータ
addr
2番目のパラメータはサーバー側のハンドラで、通常は空です。つまり、サーバー側で
http.DefaultServeMux
を処理し、サーバーサイドに書かれたビジネスロジック・ハンドラは
http.Handle()
または
http.HandleFunc()
デフォルトのインジェクション
http.DefaultServeMux
を以下のコードに追加します。
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
net/http
パッケージはまた
http.ListenAndServeTLS()
メソッドを使用します。
HTTPS
接続要求。
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error
ListenAndServeTLS()
と
ListenAndServe()
は同じ動作をしますが、違いは
HTTPS
を要求します。さらに、証明書と一致する秘密鍵を含む関連ファイルがサーバー上に存在する必要があり、例えば、以下のようになります。
certFile
に対応する
SSL certificate
ファイルパスの場合は
keyFile
対応する証明書の秘密鍵ファイルへのパスです。証明書が認証局によって署名されている場合は
certFile
パラメータには、サーバに保存されているパスを
CA
認証済み
SSL Certificate
.
3. RPC プログラミング
Goでは、標準ライブラリで提供されるnet/rpcパッケージがRPCプロトコルに必要な関連詳細を実装しており、開発者はこのパッケージを利用してRPC用のサーバサイドおよびクライアントサイドプログラムを簡単に書くことができ、Goで開発した複数のプロセス間で非常に簡単に通信を行うことができるようになっています。
net/rpc
このパッケージでは
RPC
クライアントアプリケーションは、ネットワークやその他のI/O接続を介して、リモートオブジェクトのパブリックメソッド(大文字で始まり、外部から呼び出し可能である必要があります)を呼び出すことができます。RPCサーバー上では、オブジェクトをアクセス可能なサービスとして登録し、オブジェクトのパブリックメソッドをリモートでアクセスできるようにすることができます。RPCサーバーは、異なるタイプのオブジェクトを複数登録することができますが、同じタイプのオブジェクトを複数登録することはできません。
これらの条件を満たすオブジェクトのメソッドのみが、RPCサーバーによってリモート・アクセスが可能になるように設定されます。
- オブジェクトの外部で公に呼び出すことができるメソッドでなければならない(初期値は大文字)。
- は 2 つの引数を持ち、その両方がパッケージの外側でアクセス可能な型であるか、Go ビルトインでサポートされている型でなければなりません。
- 第2引数はポインタでなければならない。 このメソッドは error 型の値を返す必要があります。
以上の4つの条件を簡単に表すと、次のようなコード行になります。
func (t *T) MethodName(argType T1, replyType *T2) error
上記のコードでは、型 T、T1、T2 はデフォルトで Go の組み込みの
encoding/gob
パッケージでエンコードとデコードを行います。
メソッドの第一引数(MethodName)は、gobのエンコードとデコードを示す。
RPC
に返すパラメータを示し、第2パラメータはクライアントから渡された
RPC
クライアントの場合、このメソッドは最終的に
error
型の値です。
RPC
サーバーは
rpc.ServeConn
を使用して、単一の接続要求を処理します。ほとんどの場合、リクエストは
TCP
または
HTTP
このサービスを作成するためにネットワークアドレスでリスニングすることは、良い選択肢です。
3.1 Go における RPC のサポートと処理
Go では、標準ライブラリが
net/rpc
パッケージは
RPC
このプロトコルを使って、開発者は簡単に RPC 用のサーバーサイドとクライアントサイドのプログラムを書くことができ、Go で開発された複数のプロセス間の通信を非常に簡単に行うことができるのです。
net/rpc
このパッケージでは
RPC
クライアントアプリケーションは、ネットワークやその他のI/O接続を介してリモートオブジェクトのパブリックメソッド(大文字で始まり、外部から呼び出し可能でなければなりません)を呼び出すことができます。その際
RPC
サーバー側では、オブジェクトをアクセス可能なサービスとして登録し、そのオブジェクトのパブリックメソッドをリモートでアクセスできるようにすることができます。A
RPC
サーバーサイドでは、異なるタイプのオブジェクトを複数登録することは可能ですが、同じタイプのオブジェクトを複数登録することはできません。
以下の条件を満たすオブジェクトのメソッドのみを
RPC
サーバーにリモートアクセスできるように設定されている。
- オブジェクトの外部で公に呼び出し可能なメソッドである必要があります(初期値は大文字)。
-
は2つの引数を持ち、両引数はパッケージの外部からアクセス可能な型でなければなりません。
Go
内部でサポートされている型。 - 第2引数はポインタでなければならない。
- メソッドは error 型の値を返さなければなりません。
以上の4つの条件を簡単に表現すると、次のような行になります。
func (t *T) MethodName(argType T1, replyType *T2) error
上記のコードでは、型 T、T1、T2 はデフォルトで Go の組み込みの
encoding/gob
パッケージでエンコードとデコードを行います。に関しては
encoding/gob
パッケージで、後述する。
このメソッドの最初のパラメータ(MethodName)は、RPCクライアントから渡されるパラメータを示し、2番目のパラメータは、RPCクライアントに返されるパラメータを示します。
RPC
を指定し、最後にエラータイプの値を返します。
RPC
サーバー側では
rpc.ServeConn
を使用して、単一の接続要求を処理します。ほとんどの場合、リクエストは
TCP
または
HTTP
このサービスを作成するためにネットワークアドレスでリスニングすることは、良い選択肢です。
3.2 Gobの紹介
Gob
のシリアル化されたデータ構造をエンコードおよびデコードするための Go ツールです。
Go
は標準ライブラリに組み込まれています。
encoding/gob
パッケージで使用することができます。を使用したデータ構造です。
Gob
は、シリアライズ後のネットワーク転送に使用することができます。
とは
JSON
または
XML
このテキストベースの記述データ交換言語は
Gob
はバイナリ符号化されたデータストリームであり
Gob
ストリームは自明であり、高い効率を確保しつつ、十分な表現力を有している。
への対応として
Go
をデータ構造のエンコードとデコードのための専用のシリアライゼーションメソッドとして使用することを意味します。
Gob
は言語を超えて使用することはできない。また
Go
は
net/rpc
パッケージの場合、データを伝送するために必要なコーデックは、デフォルトでは
Gob
. このため
Gob
のみを使用するように制限されています。
Go
言語しか使えないということです。
Go
の
RPC
はプロセス間通信を実装している。
しかし、たいていの場合、私たちは
Go
で書かれた
RPC
サーバー(またはクライアント)は、Python、Java、または他のプログラミング言語で実装されているかどうかにかかわらず、おそらく汎用的で言語に依存しないことを好むでしょう
RPC
は、クライアントと通信することができます。
3.3 エレガントなRPCインターフェースの設計
Go's
net/rpc
は、データ転送の前後にコーデックのインターフェース定義を実装しているため、柔軟性があります。つまり、開発者はデータの転送方法や、RPCサーバとクライアントがどのように相互作用するかをカスタマイズすることができるのです。
RPC
以下のコーデックインタフェースが提供されています。
type ClientCodec interface {
WriteRequest(*Request, interface{}) error
ReadResponseHeader(*Response) error
ReadResponseBody(interface{}) error
Close() error
}
type ServerCodec interface {
ReadRequestHeader(*Request) error
ReadRequestBody(interface{}) error
WriteResponse(*Response, interface{}) error
Close() error
}
インターフェース
ClientCodec
が定義しています。
RPC
クライアントがどのようにして
RPC
セッションがリクエストを送信し、レスポンスを読み取る。クライアントプログラムはリクエストを送信し、レスポンスを読み取るのに
WriteRequest()
メソッドを使ってRPCコネクションにリクエストを書き込むことができます。
ReadResponseHeader()
と
ReadResponseBody()
を使用して、サーバー側からの応答メッセージを読み取ります。全体の処理が実行されると、そのレスポンスは
Close()
メソッドを使用して接続を閉じます。
インターフェース
ServerCodec
が定義している
RPC
サーバー側がどのように新しいRPCを
RPC
セッションはリクエストを受信し、レスポンスを送信します。サーバー側のプログラムは、リクエストを
ReadRequestHeader()
と
ReadRequestBody()
メソッドは、RPC 接続から要求を読み取り、WriteResponse() メソッドを介してその接続内の RPC クライアントに応答を送信します。処理が完了すると、そのレスポンスは
Close()
メソッドで接続を閉じます。
上記のインターフェイスを実装することで、送信前後のデータのエンコードやデコードの方法を、単に
Gob
. 同様に、"Subject "セクションをカスタマイズすることも可能です。
RPC
は、サーバーサイドとクライアントサイドのインタラクションの挙動を示します。事実上
Go
標準ライブラリは
net/rpc/json
を実装するパッケージの集合です。
rpc.ClientCodec
と
rpc.ServerCodec
のインターフェースは
JSON-RPC
モジュールになります。
以上、Go言語6ネットワークプログラミング入門7チュートリアルNo.の詳細です。Go言語ネットワークプログラミングの詳細については、Scripting Houseの他の関連記事にもご注目ください
Goの学習方法
初めてGoを使う人は、こんな風に勉強するといいですよ〜。
Goを始めるための7つの記事
最初の記事 Goの紹介
第2部 プログラム構造&&データ型の紹介
タイトルVII GCガベージコレクション 3色マーカー
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン