本文包括udp客户端、udp服务器、tcp客户端、tcp服务器、http客户端、http服务器
net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。
主要实现3个步骤:初始化+发送数据+接收数据。
udp客户端
初始化+发送数据+接收数据
package main
import (
"os"
"fmt"
"net"
// "io"
)
func main() {
conn, err := net.Dial("udp", "127.0.0.1:11110")
defer conn.Close()
if err != nil {
os.Exit(1)
}
conn.Write([]byte("Hello world!"))
fmt.Println("send msg")
var msg [20]byte
conn.Read(msg[0:])
fmt.Println("msg is", string(msg[0:10]))
}
udp服务端
初始化+监听+接收数据+发送数据
package main
import (
"os"
"fmt"
"net"
)
func checkError(err error){
if err != nil {
fmt.Println("Error: %s", err.Error())
os.Exit(1)
}
}
func recvUDPMsg(conn *net.UDPConn){
var buf [20]byte
n, raddr, err := conn.ReadFromUDP(buf[0:])
if err != nil {
return
}
fmt.Println("msg is ", string(buf[0:n]))
//WriteToUDP
//func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)
_, err = conn.WriteToUDP([]byte("nice to see u"), raddr)
checkError(err)
}
func main() {
udp_addr, err := net.ResolveUDPAddr("udp", ":11110")
checkError(err)
conn, err := net.ListenUDP("udp", udp_addr)
defer conn.Close()
checkError(err)
//go recvUDPMsg(conn)
recvUDPMsg(conn)
}
tcp客户端
初始化+发送数据+接收数据
package main
import (
"fmt"
"io/ioutil"
"net"
)
func main() {
var remoteAddress, _ = net.ResolveTCPAddr("tcp4", "127.0.0.1:8080") //生成一个net.TcpAddr对像。
var conn, err = net.DialTCP("tcp4", nil, remoteAddress) //传入协议,本机地址(传了nil),远程地址,获取连接。
if err != nil { //如果连接失败。则返回。
fmt.Println("连接出错:", err)
return
}
var remoteIpAddress = conn.RemoteAddr() //获取IP地址的方法。
fmt.Println("远程IP地址是:", remoteIpAddress) //输出:220.181.111.188:80
var localIPAddress = conn.LocalAddr()
fmt.Println("本地IP地址是:", localIPAddress) //输出:192.168.1.9:45712
conn.Write([]byte("hello")) //尝试发送些信息。
fmt.Println("发送完毕: ")
//var reciverBuffer []byte //定义一个空切片,用于接收结果。
//len, err := conn.Read(reciverBuffer) //返回接收到的字节数。
fmt.Println("等待接收: ")
bys, err := ioutil.ReadAll(conn) //接收消息。
if err != nil {
fmt.Println("接收出错:", err)
}
//var reciveText = string(reciverBuffer[0:len])
var reciveText = string(bys)
fmt.Println(reciveText)
conn.Close() //关闭连接
fmt.Println("程序结束")
}
tcp服务器
初始化+监听tcp+接收连接+接收数据+发送数据
package main
import (
"fmt"
"io/ioutil"
"net"
)
func main() {
localAddress, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080") //定义一个本机IP和端口。
var tcpListener, err = net.ListenTCP("tcp", localAddress) //在刚定义好的地址上进监听请求。
if err != nil {
fmt.Println("监听出错:", err)
return
}
defer func() { //担心return之前忘记关闭连接,因此在defer中先约定好关它。
tcpListener.Close()
}()
fmt.Println("正在等待连接...")
var conn, err2 = tcpListener.AcceptTCP() //接受连接。
if err2 != nil {
fmt.Println("接受连接失败:", err2)
return
}
var remoteAddr = conn.RemoteAddr() //获取连接到的对像的IP地址。
fmt.Println("接受到一个连接:", remoteAddr)
fmt.Println("正在读取消息...")
var bys, _ = ioutil.ReadAll(conn) //读取对方发来的内容。
fmt.Println("接收到客户端的消息:", string(bys))
conn.Write([]byte("hello, Nice to meet you, my name is SongXingzhu")) //尝试发送消息。
conn.Close() //关闭连接。
}
http客户端
发送请求+解析返回结果
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
func main() {
//resp, _ := doGet("http://www.baidu.com")
//resp, _ := doPost("http://www.baidu.com", "application/json;charset=utf-8")
resp, _ := doPostForm("http://www.baidu.com")
defer resp.Body.Close() //go的特殊语法,main函数执行结束前会执行resp.Body.Close()
fmt.Println(resp.StatusCode) //有http的响应码输出
if resp.StatusCode == http.StatusOK { //如果响应码为200
body, err := ioutil.ReadAll(resp.Body) //把响应的body读出
if err != nil { //如果有异常
fmt.Println(err) //把异常打印
log.Fatal(err) //日志
}
fmt.Println(string(body)) //把响应的文本输出到console
}
}
/**
以GET的方式请求
**/
func doGet(url string) (r *http.Response, e error) {
resp, err := http.Get(url)
if err != nil {
fmt.Println(resp.StatusCode)
fmt.Println(err)
log.Fatal(err)
}
return resp, err
}
/**
以POST的方式请求
**/
func doPost(url string, bodyType string) (r *http.Response, e error) {
resp, err := http.Post(url, bodyType, nil)
if err != nil {
fmt.Println(resp.StatusCode)
fmt.Println(err)
log.Fatal(err)
}
return resp, err
}
/**
以Post表单的方式请求
**/
func doPostForm(urlStr string) (r *http.Response, e error) {
v := url.Values{"method": {"get"}, "id": {"1"}}
v.Add("name1", "1")
v.Add("name2", "2")
resp, err := http.PostForm(urlStr, v)
if err != nil {
fmt.Println(resp.StatusCode)
fmt.Println(err)
log.Fatal(err)
}
return resp, err
}
func httpDo() {
client := &http.Client{}
req, err := http.NewRequest("POST", "http://www.01happy.com/demo/accept.php", strings.NewReader("name=cjb"))
if err != nil {
// handle error
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Cookie", "name=anny")
resp, err := client.Do(req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
// handle error
}
fmt.Println(string(body))
}
发送请求+解析返回结果
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
// response, _ := http.Get("http://www.baidu.com")
// defer response.Body.Close()
// body, _ := ioutil.ReadAll(response.Body)
// fmt.Println(string(body))
client := &http.Client{}
request, _ := http.NewRequest("GET", "http://192.168.1.189:4000/bye", nil)
request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
request.Header.Set("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3")
request.Header.Set("Accept-Encoding", "gzip,deflate,sdch")
request.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")
request.Header.Set("Cache-Control", "max-age=0")
request.Header.Set("Connection", "keep-alive")
response, _ := client.Do(request)
if response.StatusCode == 200 {
body, _ := ioutil.ReadAll(response.Body)
bodystr := string(body)
fmt.Println(bodystr)
}
}
http服务器
注册服务+监听请求
package main
import (
"fmt"
"net/http"
"reflect"
"strings"
)
func hello(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello"))
}
type Handlers struct {
}
func (h *Handlers) ResAction(w http.ResponseWriter, req *http.Request) {
fmt.Println("res")
w.Write([]byte("res"))
}
func say(w http.ResponseWriter, req *http.Request) {
pathInfo := strings.Trim(req.URL.Path, "/")
fmt.Println("pathInfo:", pathInfo)
parts := strings.Split(pathInfo, "/")
fmt.Println("parts:", parts)
var action = "ResAction"
fmt.Println(strings.Join(parts, "|"))
if len(parts) > 1 {
fmt.Println("22222222")
action = strings.Title(parts[1]) + "Action"
}
fmt.Println("action:", action)
handle := &Handlers{}
controller := reflect.ValueOf(handle)
method := controller.MethodByName(action)
r := reflect.ValueOf(req)
wr := reflect.ValueOf(w)
method.Call([]reflect.Value{wr, r})
}
func main() {
http.HandleFunc("/hello", hello)
http.Handle("/handle/", http.HandlerFunc(say))
http.ListenAndServe(":8001", nil)
//select {} //阻塞进程
}
注册服务+监听请求
package main
import (
"log"
"net/http"
)
func main() {
//注册一个函数,响应某一个路由
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello this is version 1!!"))
})
//这里可以单独写一个函数传递给当前的路由
http.HandleFunc("/bye", SayBye)
log.Println("Start version v1")
log.Fatal(http.ListenAndServe(":4000", nil))
}
func SayBye(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Bye bye, this is version v1"))
log.Println("saybye")
//进行一个流式传递,将字符串转换为byte类型
}
网友评论