在GO的net包中定义了很多对网络编程操作的方法.
比如操作IP,输入IP格式地址,返回IP
package mainimport ( "net" "os" "fmt")func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s ip-addr\n", os.Args[0]) os.Exit(1) } name := os.Args[1] addr := net.ParseIP(name) if addr == nil { fmt.Println("Invalid address") } else { fmt.Println("The address is ", addr.String()) } os.Exit(0)}
客户端代码
package mainimport ( "fmt" "io/ioutil" "net" "os")func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s host:port ", os.Args[0]) os.Exit(1) } service := os.Args[1] tcpAddr, err := net.ResolveTCPAddr("tcp4", service) //获取一个IP地址转成格式 checkError(err) conn, err := net.DialTCP("tcp", nil, tcpAddr) //连接服务器,协议,本机地址,目的地址,本机地址一般为nil checkError(err) _, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n")) //请求头写进去,协议格式要把换行写清楚 checkError(err) result, err := ioutil.ReadAll(conn) checkError(err) fmt.Println(string(result)) os.Exit(0)}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) }}
然后是tcp服务端
package mainimport ( "fmt" "net" "os" "time")func main() { service := ":7777" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) //转换IP地址格式 checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) //监听端口 checkError(err) for { conn, err := listener.Accept() //等等连接 if err != nil { continue } daytime := time.Now().String() conn.Write([]byte(daytime)) // don't care about return value conn.Close() // we're finished with this client }}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) }}
然后是加了goroutine的服务端
package mainimport ( "fmt" "net" "os" "time")func main() { service := ":1200" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() if err != nil { continue } go handleClient(conn) //每次有用户连接就启动一个单独的goroutine来处理,可以处理多用户,彼此保持独立性. }}func handleClient(conn net.Conn) { defer conn.Close() //结束完后关闭连接,就是关闭用户的套接字. daytime := time.Now().String() conn.Write([]byte(daytime)) // don't care about return value // we're finished with this client}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) }}
加个长连接,判断超时
package mainimport ( "fmt" "net" "os" "time" "strconv" "strings")func main() { service := ":1200" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() if err != nil { continue } go handleClient(conn) }}func handleClient(conn net.Conn) { conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // set 2 minutes timeout request := make([]byte, 128) // set maxium request length to 128B to prevent flood attack defer conn.Close() // close connection before exit for { read_len, err := conn.Read(request) //读取连接用户发送过来的内容,括号中为大小 if err != nil { fmt.Println(err) break } if read_len == 0 { break // connection already closed by client } else if strings.TrimSpace(string(request[:read_len])) == "timestamp" { daytime := strconv.FormatInt(time.Now().Unix(), 10) conn.Write([]byte(daytime)) } else { daytime := time.Now().String() conn.Write([]byte(daytime)) } request = make([]byte, 128) //清除内容,开始下一次 }}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) }}
再就是UDP客户端
package mainimport ( "fmt" "net" "os")func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0]) os.Exit(1) } service := os.Args[1] udpAddr, err := net.ResolveUDPAddr("udp4", service) //转换IP地址 checkError(err) conn, err := net.DialUDP("udp", nil, udpAddr) //UDP连接 checkError(err) _, err = conn.Write([]byte("anything")) //发送内容 checkError(err) var buf [512]byte n, err := conn.Read(buf[0:]) //读取响应内容 checkError(err) fmt.Println(string(buf[0:n])) os.Exit(0)}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error ", err.Error()) os.Exit(1) }}
udp服务器
package mainimport ( "fmt" "net" "os" "time")func main() { service := ":1200" udpAddr, err := net.ResolveUDPAddr("udp4", service) //转换IP地址格式 checkError(err) conn, err := net.ListenUDP("udp", udpAddr) //监听IP和地址 checkError(err) for { handleClient(conn) }}func handleClient(conn *net.UDPConn) { var buf [512]byte _, addr, err := conn.ReadFromUDP(buf[0:]) //读取接收的内容 if err != nil { return } daytime := time.Now().String() conn.WriteToUDP([]byte(daytime), addr) //回复内容}func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error ", err.Error()) os.Exit(1) }}