golangでTCPを使ってみた
環境情報
go version : 1.8
os : kubuntu 16
やったこと
- LookupPort
- TCP Client
LookupPort
現在、実行してるサービスのポートを調べることができます。
net.LookupPort(network, service string) (int, error)
serviceは実行しているサービス、例えば"telent"、"http"、"ssh"とか
exsample
func main() { port, err := net.LookupPort("tcp", "http") if err != nil { fmt.Println("Error : ", err.Error()) os.Exit(2) } fmt.Println("Service port : ", port) }
TCP Client
いよいよTCPの話です。
まずはTCP関連でよく使う構造体から
type TCPAddr struct { IP IP Port int Zone string }
IPとPortとZoneを内包しています。 ZoneはIPv6で使用するZoneになります。IPとPortはそのままの意味かな。
この構造体を作るためには下記のメソッドを使います
net.ResolveTCPAddr(net, addr string) (*TCPAddr, err)
netにはネットワークタイプを(tcp, tcp4, tcp6)、addrにはアドレスとポートを入れます。 addrのフォーマットは「IPアドレスorホスト名:ポート」になります 例:www.google.com:80
次にTCPAddr構造体を使って実際にサーバとつなぎ合わせます
net.DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
netにはResolveTCPAddr同様でtcp、tcp4、tcp6のどれかを入れ、laddr、raddrにはTCPAddrを入れます。 それぞれladdrはローカル、raddrはリモートを表しています。 なので接続したいサーバのTCPAddrはraddrに入れます。(laddrには基本的にはnilが入ります)
ここで取得したTCPConnを使い実際のメッセージのやり取りを行います。 このTCPConnにたいして、write、readを行いリモートのサーバと通信を行います。
(c *TCPConn) Write(b []byte) (int, error)
bには送るメッセージを入れます(そのまんま)
最後にサーバからレスポンスを受け取り、読み込みます
ioutil.ReadAll(io.Reader) ([]byte, error)
io.Readerから読み込みます。これはサーバからレスポンスをすべて受け取るまでブロックして、すべて受け取ってから読み込みを開始します。
これで一通りTCPの通信の流れができます。 TCPクライアントのサンプルとしてHTTP通信をしたいと思います
exsample
func main() { tcpAddr, err := net.ResolveTCPAddr("tcp4", "www.google.com:80") if err != nil { fmt.Println("net resolve TCP Addr error ") os.Exit(1) } conn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { fmt.Println("net dial tcp error ") os.Exit(1) } _, err = conn.Write([]byte{"HEAD / HTTP/1.0 \r\n\r\n) if err != nil { fmt.Println("conn write error ") os.Exit(1) } result, err := ioutil.ReadAll(conn) if err != nil { fmt.Println("ioutil read all error ") os.Exit(1) } fmt.Println(string(result)) }
これでTCP通信ができるようになりました(やーー!!)