GO WEB
1、第一个坑的就是,错误信息如下:
比较常见的错误“Connection reset by peer”,该错误和“Connection reset”是有区别的:
服务器返回了“RST”时,如果此时客户端正在从Socket套接字的输出流中读数据则会提示Connection reset”;
服务器返回了“RST”时,如果此时客户端正在往Socket套接字的输入流中写数据则会提示“Connection reset by peer”。
所以,很坑爹的一个就是,在连接TCP后,不能直接写数据,要让他睡睡。。。
下面是一个得到系统时间的server
也就是,我都还没第三次握手,我就send数据了。GG
https://my.oschina.net/xionghui/blog/508758
package main import ( "fmt" "net" "os" "time" ) func main() { server := ":7777" tcpAddr, err := net.ResolveTCPAddr("tcp4", server) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) // pay atttion checkError(err) for { conn, err := listener.Accept() if err != nil { continue } fmt.Println(conn.RemoteAddr()) go solve(conn) } } func solve(conn net.Conn) { defer conn.Close() dayTime := time.Now().String() conn.Write([]byte(dayTime)) fmt.Println("teset") } func checkError(err error) { if err != nil { fmt.Println(err) os.Exit(-1) } }
package main import ( "fmt" "io/ioutil" "net" "os" "time" ) func main() { tcpAddr, errOne := net.ResolveTCPAddr("tcp", "127.0.0.1:7777") checkError(errOne) conn, errTwo := net.DialTCP("tcp", nil, tcpAddr) defer conn.Close() checkError(errTwo) time.Sleep(time.Second * 2) // 睡睡 _, errThrid := conn.Write([]byte("hello")) checkError(errThrid) result, errOne := ioutil.ReadAll(conn) checkError(errOne) fmt.Println(string(result)) } func checkError(err error) { if err != nil { fmt.Println(err) os.Exit(-1) } }
2、socket的读取数据很bug啊,如果读取数据不合适,就会一直卡在那儿,很头痛。
TCP版本的聊天程序,用一个bufio.NewReader(TCPconn)来读取
package main import ( "bufio" "fmt" // "io/ioutil" "net" "os" "strings" "time" ) var ch chan string = make(chan string, 10) func main() { conn := newConnect() conn.SetNoDelay(false) fmt.Println("please enter your name") input := bufio.NewReader(os.Stdin) b, _, err := input.ReadLine() checkError(err) name := string(b) conn.Write([]byte("add " + name)) // go func(conn net.Conn) { // respond, err := ioutil.ReadAll(conn) // checkError(err) // if respond != "" { // fmt.Println(string(respond)) // } // }(conn) //go getMessage(conn) go getMessage(conn) go showMessage() for { time.Sleep(time.Microsecond * 200) // helpUse() //conn = newConnect() request, err := input.ReadString('\n') checkError(err) _, err1 := conn.Write([]byte(request)) checkError(err1) } defer conn.Close() } func getMessage(conn *net.TCPConn) { // var b []byte // read_len, err := conn.Read(b) // checkError(err) // return string(b[:read_len]) // respond, err := ioutil.ReadAll(conn) // checkError(err) // return string(respond) // // fmt.Println("ff") // var b []byte // read_len, err := conn.Read(b) // fmt.Println("gg") // checkError(err) // fmt.Println(string(b[:read_len])) // fmt.Print("\n") r := bufio.NewReader(conn) for { str, err := r.ReadString('\n') checkError(err) res := strings.Split(str, "E") // ch <- "\n" for _, value := range res { if value == "\n" { // fmt.Print("\n") ch <- "\n" continue } // fmt.Println(value) ch <- value } } } func showMessage() { for { res := <-ch if res == "\n" { fmt.Println("") } else { fmt.Println(res) } } } func helpUse() { fmt.Println("------------------") fmt.Println("1、add user") fmt.Println("2、list all user online") fmt.Println("3、send message to xxx with text") fmt.Println("------------------") } func newConnect() *net.TCPConn { tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8282") checkError(err) conn, err := net.DialTCP("tcp", nil, tcpAddr) checkError(err) return conn } func checkError(err error) { if err != nil { fmt.Println(err) os.Exit(-1) } }
package main import ( "fmt" "net" "os" "strings" "typeDefine" ) var Muser typeDefine.TotalUser func main() { Muser.OnlineUser = make([]*typeDefine.User, 0, 10) Muser.Mp = make(map[string]*net.TCPConn) service := ":8282" tcpAddr, err := net.ResolveTCPAddr("tcp", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.AcceptTCP() fmt.Println("new user come") if err != nil { continue } go solve(conn) } } func solve(conn *net.TCPConn) { // conn.SetWriteBuffer(0) defer conn.Close() b := make([]byte, 512) //看看是否需要放入去,这个也不清零啊 var name string for { readLen, err := conn.Read(b) if readLen == 0 { fmt.Println("bye~") return } checkError(err) request := strings.Split(string(b[:readLen]), " ") fmt.Println(request) // conn.Write([]byte("helloE")) // continue if request[0] == "ADD" || request[0] == "add" { if name != "" { continue } name = request[1] Muser.AddUser(request[1], conn) Muser.Mp[request[1]] = conn } else if request[0] == "LIST" || request[0] == "list" { Muser.ShowAllUserOnline(conn) } else { var tot string = name + " say: " for i := 1; i < len(request); i++ { tot += request[i] tot += " " } Muser.SendMessage(name, request[0], tot) } } } func checkError(err error) { if err != nil { fmt.Println(err) os.Exit(-1) } } // -----------------
package typeDefine import ( // "fmt" "net" ) const MAXN = 10 type TotalUser struct { OnlineUser []*User Mp map[string]*net.TCPConn } type User struct { Mes chan string Name string } func (user *TotalUser) AddUser(name string, conn net.Conn) { if user.ExitUser(name, "") { conn.Write([]byte("unsuccessfully, the user " + name + " is already exits\n")) return } newUser := &User{nil, name} newUser.Mes = make(chan string, MAXN) user.OnlineUser = append(user.OnlineUser, newUser) conn.Write([]byte("Login successfully\n")) return } func (user *TotalUser) SendMessage(from string, to string, text string) { for i := range user.OnlineUser { onlineName := user.OnlineUser[i].Name if onlineName == from { continue } if onlineName == to { conn, _ := user.Mp[to] conn.Write([]byte(text + "\n")) return } } } func (user *TotalUser) ExitUser(findName string, expectName string) bool { for i := range user.OnlineUser { if user.OnlineUser[i].Name == expectName { continue } if user.OnlineUser[i].Name == findName { return true } } return false } func (user *TotalUser) ShowAllUserOnline(conn net.Conn) { for i := range user.OnlineUser { conn.Write([]byte(user.OnlineUser[i].Name + " onlineE")) //fmt.Println(user.OnlineUser[i].Name + " online") } conn.Write([]byte("\n")) }
3、按任意键退出
fmt.Scanln()
4、超时机制,查看routines是否超时
可以用 <- time.After(time.Second)
https://gobyexample.com/timeouts
5、基于udp的聊天程序,
用udpListener.ReadFromUDP即可
bug1、还是读入问题,读入一行可以使用
input := bufio.NewScanner(os.Stdin)
input.Scan()
input.Text()
bgu2、map不了指针??所以把*net.UdpConn转换成string来map了
基本思路是:
1️⃣、
知道服务器监听的端口,LocalHost + ServerPort
然后客户端也是要监听端口的(看起来和服务器一样),因为服务器也要发送消息给它,服务器要记录客户端监听了什么端口
一个端口不能两个东西同时监听,所以客户端的监听端口要rand出来。同时要告诉服务器我监听的端口,然后服务器就可能链接去你这里了。
2️⃣、
心跳包可以使用Ticker实现,但是我这里没实现
reference http://blog.csdn.net/ssnian_/article/details/22949965
3️⃣、可以用default来断开链接,清除记录了的数据,因为本来是客户端等待数据进入,一开始是空stirng,或者是quit,然后关闭客户端后,就是相当于控制台没输入,然后就是一开始的stirng值,(客户端也会进入一次判断的) 就相当于quit。
package main import ( "errors" "fmt" "net" "os" "strings" ) type User struct { Name string userConn *net.UDPConn ChatConn *net.UDPConn } var ErrorCode = 1 //监听的端口 && 地址 var ServerPort = ":1212" var LocalHost = "127.0.0.1" // var isOnline = make(map[string]*net.UDPConn) var isUdpAddr = make(map[string]string) var userSlice = make([]User, 0) //心跳包检查,检测用户是否在线 func HeartCheck() { } // 得到连接 func getUdpConn(udpAddr string) (*net.UDPConn, error) { // fmt.Println("+++", udpAddr) // fmt.Println(isOnline["vimi"]) // fmt.Println(isUdpAddr[udpAddr]) if value, ok := isUdpAddr[udpAddr]; ok { if udpConn, ok := isOnline[value]; ok { return udpConn, nil } } fmt.Println("not found this user") return nil, errors.New("not found this user") } func UdpHandle(udpListener *net.UDPConn) { buff := make([]byte, 128) readLen, udpAddr, err := udpListener.ReadFromUDP(buff) //得到udp地址,就是那个用户的 CheckError(err) // fmt.Printf("%+v %d\n", udpAddr, readLen) go func() { if readLen > 0 { request := parseBuffer(buff, readLen) // 输出请求参数, debug fmt.Println("---------") for _, value := range request { fmt.Println(value) } fmt.Println("**********") switch request[0] { case "add": //找到用户监听的端口 userUdpAddr, err := net.ResolveUDPAddr("udp", LocalHost+":"+request[2]) CheckError(err) connClient, err := net.DialUDP("udp", nil, userUdpAddr) // 链接过去 CheckError(err) isOnline[request[1]] = connClient isUdpAddr[udpAddr.String()] = request[1] fmt.Println(udpAddr, " 上线了") userSlice = append(userSlice, User{request[1], connClient, nil}) case "show": connClient, err := getUdpConn(udpAddr.String()) if err != nil { break } for _, value := range userSlice { // 这个有bug,没删除元素,还没管理 sendMessage(value.Name+" online", connClient) } case "chat": connClient, err := getUdpConn(udpAddr.String()) if err != nil { break } _, ok := isOnline[request[1]] if !ok { sendMessage("user "+request[1]+" off line", connClient) break } context := "" for i := 2; i < len(request); i++ { context += request[i] context += " " } sendMessage(context, isOnline[request[1]]) default: fmt.Println("bye~") name := isUdpAddr[udpAddr.String()] for i := 0; i < len(userSlice); i++ { if userSlice[i].Name == name { if len(userSlice) == 1 { userSlice = make([]User, 0) } else if i == 0 { userSlice = userSlice[1:] } else if i == len(userSlice)-1 { userSlice = userSlice[:len(userSlice)-1] } else { userSlice = userSlice[:i] userSlice = append(userSlice, userSlice[i+1:]...) } break } } delete(isOnline, isUdpAddr[udpAddr.String()]) delete(isUdpAddr, udpAddr.String()) } } else { fmt.Println("bye bye") delete(isOnline, isUdpAddr[udpAddr.String()]) delete(isUdpAddr, udpAddr.String()) } }() } func sendMessage(context string, conn *net.UDPConn) { conn.Write([]byte(context)) } // 把请求翻译出来 func parseBuffer(buff []byte, readLen int) []string { buffString := string(buff[:readLen]) request := strings.Split(buffString, " ") return request } func main() { udpAddr, err := net.ResolveUDPAddr("udp", LocalHost+ServerPort) CheckError(err) udpListener, err := net.ListenUDP("udp", udpAddr) CheckError(err) defer udpListener.Close() go HeartCheck() fmt.Println("开始监听") for { UdpHandle(udpListener) } } func CheckError(err error) { if err != nil { fmt.Println(err) os.Exit(ErrorCode) } }
package main import ( "bufio" "fmt" "math/rand" "net" "os" "strconv" "time" ) var ErrorCode = 1 //监听的端口 && 地址 var ServerPort = ":1212" var LocalHost = "127.0.0.1" //判断是否已经使用该端口 var isUsePort = make(map[int]bool) var op = map[string]string{ "登录": "add ", "显示在线人数": "show ", "聊天": "chat ", } func CheckError(err error) { if err != nil { fmt.Println(err) os.Exit(ErrorCode) } } func getMessage(udpListener *net.UDPConn) { for { var buff = make([]byte, 128) readLen, _, err := udpListener.ReadFromUDP(buff) CheckError(err) if readLen > 0 { fmt.Println(string(buff[:readLen])) } } } func getUdpListener() (*net.UDPConn, int) { newSeed := rand.NewSource(int64(time.Now().Second())) newRand := rand.New(newSeed) for { randPort := newRand.Intn(3000) + 2000 if _, ok := isUsePort[randPort]; ok { continue } //fmt.Println(randPort) isUsePort[randPort] = true udpAddr, err := net.ResolveUDPAddr("udp", LocalHost+":"+strconv.Itoa(randPort)) CheckError(err) udpListener, err := net.ListenUDP("udp", udpAddr) CheckError(err) return udpListener, randPort } } func main() { var intServerPort int for i := 1; i < len(ServerPort); i++ { intServerPort = intServerPort*10 + int(ServerPort[i]-'0') } isUsePort[intServerPort] = true udpAddr, err := net.ResolveUDPAddr("udp", LocalHost+ServerPort) CheckError(err) udpConn, err := net.DialUDP("udp", nil, udpAddr) CheckError(err) udpListener, port := getUdpListener() defer udpConn.Close() defer udpListener.Close() name := "" fmt.Println("please enter your name") fmt.Scanf("%s", &name) udpConn.Write([]byte(op["登录"] + name + " " + strconv.Itoa(port))) go getMessage(udpListener) input := bufio.NewScanner(os.Stdin) for { opp := "" fmt.Scanf("%s", &opp) if opp == "show" { udpConn.Write([]byte(op["显示在线人数"])) } else if opp == "chat" { input.Scan() udpConn.Write([]byte(op["聊天"] + input.Text() + " text by " + name)) } else { udpConn.Write([]byte("quit")) break } } }
----------------------------------
go web like java forward 跳转
http.Redirect(w, r, "/show", http.StatusFound)
go use telegram(token改变了的)
package main import ( "bytes" "encoding/json" "fmt" "io" "log" "net" "net/http" "net/url" "strconv" "time" ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" ) var config struct { server string port int password string method string } func handleError(err error) { if err != nil { log.Fatal(err) } } func HTTPClientBySocks5(uri string) *http.Client { parsedURL, err := url.Parse(uri) handleError(err) host, _, err := net.SplitHostPort(parsedURL.Host) if err != nil { if parsedURL.Scheme == "https" { host = net.JoinHostPort(parsedURL.Host, "443") } else { host = net.JoinHostPort(parsedURL.Host, "80") } } else { host = parsedURL.Host } rawAddr, err := ss.RawAddr(host) handleError(err) serverAddr := net.JoinHostPort(config.server, strconv.Itoa(config.port)) cipher, err := ss.NewCipher(config.method, config.password) handleError(err) dailFunc := func(network, addr string) (net.Conn, error) { return ss.DialWithRawAddr(rawAddr, serverAddr, cipher.Copy()) } //dailContext := func(ctx context.Context, network, addr string) (net.Conn, error) {} tr := &http.Transport{ MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } tr.Dial = dailFunc return &http.Client{Transport: tr} } func Get(uri string) (resp *http.Response, err error) { client := HTTPClientBySocks5(uri) return client.Get(uri) } func Post(uri string, contentType string, body io.Reader) (resp *http.Response, err error) { client := HTTPClientBySocks5(uri) return client.Post(uri, contentType, body) } func PostForm(uri string, data url.Values) (resp *http.Response, err error) { client := HTTPClientBySocks5(uri) return client.PostForm(uri, data) } func Head(uri string) (resp *http.Response, err error) { client := HTTPClientBySocks5(uri) return client.Head(uri) } type two struct { Text string `json:"text"` Url string `json:"url"` } type one struct { InlineKeyBodard [][]*two `json:"inline_keyboard"` } type Message struct { ChatID string `json:"chat_id"` Text string `json:"text"` ReplyMarkup *one `json:"reply_markup"` ParseMode string `json:"parse_mode"` } func testMe() { item := &two{"go", "www.google.com"} temp := &one{[][]*two{}} t := []*two{} t = append(t, item) t = append(t, item) temp.InlineKeyBodard = append(temp.InlineKeyBodard, t) msg := &Message{ ChatID: "-264517585", Text: "[test](www.baidu.com)", ReplyMarkup: temp, ParseMode: "markdown", } b, _ := json.Marshal(msg) re := bytes.NewBuffer(b) // fmt.Println(msg) fmt.Println(string(b)) Post("https://api.telegram.org/bot516690928:AAH4l2EyC8YAFalLut6oWv-1BrqgoAkfo/sendMessage", "application/json", re) } func main() { // for testing config.method = "aes-256-cfb" // default method config.password = "stupidone" config.port = 1080 // your port config.server = "95.163.202.160" testMe() // var uri string = "https://api.telegram.org/bot516690928:AAH4EyC8YAFalLut6ZMoWv-1BrqgoAkfo/getMe" // resp, err := Get(uri) // handleError(err) // defer resp.Body.Close() // body, err := ioutil.ReadAll(resp.Body) // handleError(err) // fmt.Println(string(body)) }
这里想记录的是json出一个button是怎样做的,对应下面的
http://donggu.me/2018/03/15/Telegram%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/
golang http.get走本地代理
golang走代理
package main import ( "fmt" "io/ioutil" "net/http" "os" "time" "golang.org/x/net/proxy" ) func main() { go func() { select { case <-time.After(time.Second * 10): break } os.Exit(1) }() dialSocksProxy, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct) if err != nil { fmt.Println("Error connecting to proxy:", err) return } tr := &http.Transport{Dial: dialSocksProxy.Dial} // Create client myClient := &http.Client{ Transport: tr, } response, err := myClient.Get("https://api.telegram.org/bot516690928:AAH4EyC8YAFalLut6ZMoWv-1BrqgoAkfo/getMe") if err != nil { fmt.Println(err) return } defer response.Body.Close() var by []byte by, _ = ioutil.ReadAll(response.Body) fmt.Println(string(by)) }
--------------------------------------------------------------------------------------------------------------------------------------------
golang写后台,java写client
package main import ( "fmt" "net" "github.com/sirupsen/logrus" ) const ( addr = ":7070" netWork = "tcp" ) func checkErr(err error) { if err != nil { logrus.Error(err) } } func main() { tcpAddr, err := net.ResolveTCPAddr(netWork, addr) checkErr(err) s, err := net.ListenTCP(netWork, tcpAddr) checkErr(err) for { fmt.Println("new") conn, err := s.AcceptTCP() if err != nil { logrus.Error(err) continue } go solve(conn) } } func solve(conn *net.TCPConn) { defer conn.Close() b := make([]byte, 512) for { readLen, err := conn.Read(b) if readLen == 0 { fmt.Println("bye~") return } if err != nil { logrus.Error(err) continue } fmt.Println(string(b)) _, err = conn.Write([]byte("Send OK\n")) // time.Sleep(time.Second) checkErr(err) } }
package main import ( "bufio" "fmt" "net" "github.com/sirupsen/logrus" ) const ( addr = "47.106.195.179:7070" netWork = "tcp" ) func checkErr(err error) { if err != nil { logrus.Error(err) } } func main() { tcpAddr, err := net.ResolveTCPAddr(netWork, addr) checkErr(err) conn, err := net.DialTCP(netWork, nil, tcpAddr) checkErr(err) _, err = conn.Write([]byte("This is my homework of network ,I am happy!")) checkErr(err) r := bufio.NewReader(conn) b, _, err := r.ReadLine() checkErr(err) fmt.Println(string(b)) }
package room.vimi.crawler; import java.io.BufferedReader; import java.io.IOException; import java.io.*; import java.net.Socket; import java.net.UnknownHostException; public class App { public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("47.106.195.179", 7070); InputStreamReader reader = new InputStreamReader(socket.getInputStream()); BufferedReader buffer_reader = new BufferedReader(reader); PrintWriter writer = new PrintWriter(socket.getOutputStream()); String one = "hello"; writer.println(one); writer.flush(); String res = buffer_reader.readLine(); System.out.println(res); } }
posted on 2018-02-02 18:59 stupid_one 阅读(411) 评论(0) 编辑 收藏 举报