go语言socket编程

go语言socket编程

用go写socket非常简单,如果你了解其他语言的socket的话一看便知,如果想深入的话,个人建议看uninx网络编程套接字联网API这本书。

在go中,网络协议被封装的非常完好了,我们并不需要像其他语言那样需要socket、bind、listen、receive、connect等一系列的操作,只需要go中自带的net包就可以很方便的完成socket编程。

server.go

package main  
import (  
    "fmt"  
    "net"  
    "log"  
    "os"  
)  

func main() {  
    //建立socket,监听端口  
    netListen, err := net.Listen("tcp", "localhost:1024")  
    CheckError(err)  
    defer netListen.Close()  

    Log("Waiting for clients")  
    for {  
        conn, err := netListen.Accept()  
        if err != nil {  
            continue  
        }  
        Log(conn.RemoteAddr().String(), " tcp connect success")  
        handleConnection(conn)  
    }  
}  
//处理连接  
func handleConnection(conn net.Conn) {  
    buffer := make([]byte, 2048)  
    for { 
        n, err := conn.Read(buffer)  
        if err != nil {
            Log(conn.RemoteAddr().String(), " connection error: ", err)  
            return  
        }  
        Log(conn.RemoteAddr().String(), "receive data string:\n", string(buffer[:n]))  
    }
}

func CheckError(err error) {  
    if err != nil {  
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
        os.Exit(1)  
    }  
}   

client.go

这里客户端使用stdin读取输入,具体情况请大家自己运行实例中的代码即可

package main  

import (  
    "fmt"  
    "net"  
    "os"  
    "bufio"
)  

func sender(conn net.Conn) {
    r := bufio.NewReader(os.Stdin) /*使用bufio缓冲器*/
    for{
        rawLine, _, _ := r.ReadLine()
        line := string(rawLine)
        conn.Write([]byte(line))  
        fmt.Println("send over") 
    }
}  

func main() {    
    tcpAddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:1024")  
    if err != nil {  
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
        os.Exit(1)  
    }  

    conn, err := net.DialTCP("tcp", nil, tcpAddr)  
    if err != nil {  
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
        os.Exit(1)  
    }  

    fmt.Println("connect success")  
    sender(conn)  
}  

大家看看,是不是很简单呢。server端主要用到Listen、Accept、Read三个主要的函数

    netListen, err := net.Listen("tcp", "localhost:1024") 
    conn, err := netListen.Accept() 
    n, err := conn.Read(buffer)  

client端就用到DialTCP这个主要的api,请大家自行查阅这个函数的用法.
Go语言中通过net包中的DialTCP函数建议一个TCP连接,返回一个TCPConn类型,客户端和服务器段通过这个类型来进行数据交换。一般而言,客户端通过TCPConn写入请求信息发送到服务器端,读取服务器端反馈的信息。这个链接只有当任意一遍关闭了连接之后才失效,不然我们都可以一直使用。函数定义

func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error)
  • net参数是”tcp4”、”tcp6”、”tcp”中的任意一个,分别表示TCPv4、TCPv6或者任意
  • laddr表示本机地址,一般设置为nil
  • addr表示远程的服务地址 例如127.0.0.1:9000

net包中有一个类型TCPConn,这个类型可以用来作为客户端和服务器端交互的通道,他有两个主要的函数:

func (c *TCPConn) Write(b []byte) (n int, err os.Error)
func (c *TCPConn) Read(b []byte) (n int, err os.Error)

通过以上这个例子我们就可以搭建一个socket的server-clinet框架。
如果在handleConnection(conn net.Conn)这句前面加一个go就可以让服务端并发的出来不同的client了,其中go是go语言中的关键字,go语言中支持轻量级线程(协程)goroutine

你可能感兴趣的:(go)