2011-09-22 43 views
3

例如,具有基本的分組協議,如:如何在Go中有效使用網絡功能?

[packetType INT] [分組ID INT] [數據[]字節]

,使一個客戶端和服務器用它做簡單的事情(EGX,聊天。 )

+0

http://senseis.xmp.net/?PagesForBeginners(抱歉...) – MatthieuW

+0

我不認爲這是重要的。 :P –

回答

5

這裏是一個客戶端和服務器,處理冗長的恐慌錯誤。它們有一些限制:

  • 服務器一次只處理一個客戶端連接。你可以通過使用goroutines來解決這個問題。
  • 數據包總是包含100個字節的有效載荷。你可以通過在一個地方放一個長度的數據包來解決這個問題,而不是使用整個結構體的編碼/二進制數,但是我保持簡單。

這裏的服務器:

package main 

import (
    "encoding/binary" 
    "fmt" 
    "net" 
) 

type packet struct { 
    // Field names must be capitalized for encoding/binary. 
    // It's also important to use explicitly sized types. 
    // int32 rather than int, etc. 
    Type int32 
    Id int32 
    // This must be an array rather than a slice. 
    Data [100]byte 
} 

func main() { 
    // set up a listener on port 2000 
    l, err := net.Listen("tcp", ":2000") 
    if err != nil { 
     panic(err.String()) 
    } 

    for { 
     // start listening for a connection 
     conn, err := l.Accept() 
     if err != nil { 
      panic(err.String()) 
     } 
     handleClient(conn) 
    } 
} 

func handleClient(conn net.Conn) { 
    defer conn.Close() 

    // a client has connected; now wait for a packet 
    var msg packet 
    binary.Read(conn, binary.BigEndian, &msg) 
    fmt.Printf("Received a packet: %s\n", msg.Data) 

    // send the response 
    response := packet{Type: 1, Id: 1} 
    copy(response.Data[:], "Hello, client") 
    binary.Write(conn, binary.BigEndian, &response) 
} 

這裏的客戶端。它發送一個數據包類型爲0,ID爲0,內容爲「Hello,server」的數據包。然後等待迴應,打印出來並退出。

package main 

import (
    "encoding/binary" 
    "fmt" 
    "net" 
) 

type packet struct { 
    Type int32 
    Id int32 
    Data [100]byte 
} 

func main() { 
    // connect to localhost on port 2000 
    conn, err := net.Dial("tcp", ":2000") 
    if err != nil { 
     panic(err.String()) 
    } 
    defer conn.Close() 

    // send a packet 
    msg := packet{} 
    copy(msg.Data[:], "Hello, server") 
    err = binary.Write(conn, binary.BigEndian, &msg) 
    if err != nil { 
     panic(err.String()) 
    } 

    // receive the response 
    var response packet 
    err = binary.Read(conn, binary.BigEndian, &response) 
    if err != nil { 
     panic(err.String()) 
    } 
    fmt.Printf("Response: %s\n", response.Data) 
} 
+0

你可以在結構中使用編碼/二進制和[]字節嗎? –

+0

panic:binary.Write:無效類型main.packet –

+0

我以爲你可以,但顯然你不能。無論如何,它都會有問題。對不起,我必須稍後再糾正。 –