一、通过socket我们模拟请求网易
package main;import ( "net" "log" "io/ioutil" "fmt")func chkError(err error) { if err != nil { log.Fatal(err); }}func main() { //我们模拟请求网易的服务器 //ResolveTCPAddr用于获取一个TCPAddr //net参数是"tcp4"、"tcp6"、"tcp" //addr表示域名或IP地址加端口号 tcpaddr, err := net.ResolveTCPAddr("tcp4", "www.163.com:80"); chkError(err); //DialTCP建立一个TCP连接 //net参数是"tcp4"、"tcp6"、"tcp" //laddr表示本机地址,一般设为nil //raddr表示远程地址 tcpconn, err2 := net.DialTCP("tcp", nil, tcpaddr); chkError(err2); //向tcpconn中写入数据 _, err3 := tcpconn.Write([]byte("GET / HTTP/1.1 \r\n\r\n")); chkError(err3); //读取tcpconn中的所有数据 data, err4 := ioutil.ReadAll(tcpconn); chkError(err4); //打印出数据 fmt.Println(string(data));}
二、通过socket创建简单的服务端
package main;import ( "net" "log")func chkError(err error) { if err != nil { log.Fatal(err); }}func main() { //创建一个TCP服务端 tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080"); chkError(err); //监听端口 tcplisten, err2 := net.ListenTCP("tcp", tcpaddr); chkError(err2); //死循环的处理客户端请求 for { //等待客户的连接 //注意这里是无法并发处理多个请求的 conn, err3 := tcplisten.Accept(); //如果有错误直接跳过 if err3 != nil { continue; } //向客户端发送数据,并关闭连接 conn.Write([]byte("hello,client \r\n")); conn.Close(); }}
通过xshell的telnet方法测试。
三、改进上面的代码,使用goroutine来处理用户的请求
package main;import ( "log" "net" "time")func chkError(err error) { if err != nil { log.Fatal(err); }}//单独处理客户端的请求func clientHandle(conn net.Conn) { defer conn.Close(); conn.Write([]byte("hello " + time.Now().String()));}func main() { //创建一个TCP服务端 tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080"); chkError(err); //监听端口 tcplisten, err2 := net.ListenTCP("tcp", tcpaddr); chkError(err2); //死循环的处理客户端请求 for { //等待客户的连接 conn, err3 := tcplisten.Accept(); //如果有错误直接跳过 if err3 != nil { continue; } //通过goroutine来处理用户的请求 go clientHandle(conn); }}
四、连续的处理客户端发送的请求,根据cmd命令不同,返回不同数据。
package main;import ( "net" "time" "log" "strings")func chkError(err error) { if err != nil { log.Fatal(err); }}//单独处理客户端的请求func clientHandle(conn net.Conn) { //设置当客户端3分钟内无数据请求时,自动关闭conn conn.SetReadDeadline(time.Now().Add(time.Minute * 3)); defer conn.Close(); //循环的处理客户的请求 for { data := make([]byte, 256); //从conn中读取数据 n, err := conn.Read(data); //如果读取数据大小为0或出错则退出 if n == 0 || err != nil { break; } //去掉两端空白字符 cmd := strings.TrimSpace(string(data[0:n])); //发送给客户端的数据 rep := ""; if(cmd == "string") { rep = "hello,client \r\n"; } else if (cmd == "time") { rep = time.Now().Format("2006-01-02 15:04:05"); } //发送数据 conn.Write([]byte(rep)); }}func main() { tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080"); chkError(err); tcplisten, err2 := net.ListenTCP("tcp", tcpaddr); chkError(err2); for { conn, err3 := tcplisten.Accept(); if err3 != nil { continue; } go clientHandle(conn); }}