2017-05-24 33 views
2

私はgolangのシンプルなチャットサーバーとクライアントに取り組んでいます。私はネットからのメッセージを読むことにいくつか問題があります。これまでの私のやり方は次のとおりです。bufio.NewReader(conn)で全体のメッセージを読む

bufio.NewReader(conn).ReadString('\n') 

ユーザがメッセージを送信するために「\ n」まで読む必要があるためです。しかし、現在私は暗号化に取り組んでいます。クライアントとサーバーの間で公開鍵を送信するときに、キーに '\ n'が含まれることがあり、キー全体を取得するのが難しくなります。私はちょうど特定の文字で停止するのではなく、全体のメッセージをどのように読むことができるのだろうかと思っています。ありがとう!

+0

TCPはストリーム指向のプロトコルであり、「メッセージ」を持たない。あなたのメッセージをフレーム化するには、別のプロトコルが必要です。あなたは単に長さ接頭辞、ネットストリング、bencode、HTTPを使用することができます、多くのオプションがあります。 – JimB

+0

@JimB長さ接頭辞を使用した簡単な例を教えてください。これはゴランを使った私の最初のプロジェクトで、ネットワーキングに関する多くの経験はありません。ありがとう。 –

+1

フレーミングの問題とは別に、バッファが破棄されるため、 'bufio.NewReader(conn).ReadString( '\ n')というコードが問題の原因になります。 bufio.Readerは、接続ごとに1回作成します。アプリケーションが接続から読み取るたびに作成するのではありません。 –

答えて

3

バイナリデータを送信する簡単なオプションは、長さ接頭辞を使用することです。データサイズを32ビットビッグエンディアンの整数としてエンコードし、そのデータ量を読み込みます。

// create the length prefix 
prefix := make([]byte, 4) 
binary.BigEndian.PutUint32(prefix, uint32(len(message))) 

// write the prefix and the data to the stream (checking errors) 
_, err := conn.Write(prefix) 
_, err = conn.Write(message) 

とメッセージを読むために

// read the length prefix 
prefix := make([]byte, 4) 
_, err = io.ReadFull(conn, prefix) 


length := binary.BigEndian.Uint32(prefix) 
// verify length if there are restrictions 

message = make([]byte, int(length)) 
_, err = io.ReadFull(conn, message) 

参照してくださいあなたはまた、もちろん、メッセージングのニーズになどHTTP、IRC、のような既存の、ほかの試験プロトコルを、使用することができますもGolang: TCP client/server data delimiter

。 go stdライブラリには、単純なtextproto packageが付属しています。あるいは、JSONのような一様なエンコーディングでメッセージを囲むこともできます。

関連する問題