golang Go中的虚拟UDP孔冲孔样本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang Go中的虚拟UDP孔冲孔样本相关的知识,希望对你有一定的参考价值。

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
)

var userIP map[string]string

type ChatRequest struct {
	Action   string
	Username string
	Message  string
}

func main() {
	userIP = map[string]string{}
	service := ":9999"
	udpAddr, err := net.ResolveUDPAddr("udp4", service)
        if err != nil {
                log.Fatal(err)
        }

	conn, err := net.ListenUDP("udp", udpAddr)
        if err != nil {
                log.Fatal(err)
        }

	for {
		handleClient(conn)
	}
}

/*
   Action:
           New -- Add a new user
           Get -- Get a user IP address
   Username:
           New -- New user's name
           Get -- The requested user name
*/
func handleClient(conn *net.UDPConn) {
	var buf [2048]byte

	n, addr, err := conn.ReadFromUDP(buf[0:])
	if err != nil {
		return
	}

	var chatRequest ChatRequest
	err = json.Unmarshal(buf[:n], &chatRequest)
	if err != nil {
		log.Print(err)
		return
	}

	switch chatRequest.Action {
	case "New":
		remoteAddr := fmt.Sprintf("%s:%d", addr.IP, addr.Port)
		fmt.Println(remoteAddr, "connecting")
		userIP[chatRequest.Username] = remoteAddr

		// Send message back
		messageRequest := ChatRequest{
			"Chat",
			chatRequest.Username,
			remoteAddr,
		}
		jsonRequest, err := json.Marshal(&messageRequest)
		if err != nil {
			log.Print(err)
			break
		}
		conn.WriteToUDP(jsonRequest, addr)
	case "Get":
		// Send message back
                peerAddr := ""
                if _, ok := userIP[chatRequest.Message]; ok {
                        peerAddr = userIP[chatRequest.Message]
                }

		messageRequest := ChatRequest{
			"Chat",
			chatRequest.Username,
                        peerAddr,
		}
		jsonRequest, err := json.Marshal(&messageRequest)
		if err != nil {
			log.Print(err)
			break
		}
		_, err = conn.WriteToUDP(jsonRequest, addr)
		if err != nil {
			log.Print(err)
		}
	}
	fmt.Println("User table:", userIP)
}
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"os"
	"time"
)

type ChatRequest struct {
	Action   string
	Username string
	Message  string
}

func main() {
	if len(os.Args) < 5 {
		log.Fatal("Usage: ", os.Args[0], " port serverAddr username peername")
	}
	port := fmt.Sprintf(":%s", os.Args[1])
	serverAddr := os.Args[2]
	username := os.Args[3]
	peer := os.Args[4]
	buf := make([]byte, 2048)

	// Prepare to register user to server.
	saddr, err := net.ResolveUDPAddr("udp4", serverAddr)
	if err != nil {
		log.Print("Resolve server address failed.")
		log.Fatal(err)
	}

	// Prepare for local listening.
	addr, err := net.ResolveUDPAddr("udp4", port)
	if err != nil {
		log.Print("Resolve local address failed.")
		log.Fatal(err)
	}
	conn, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Print("Listen UDP failed.")
		log.Fatal(err)
	}

	// Send registration information to server.
	initChatRequest := ChatRequest{
		"New",
		username,
		"",
	}
	jsonRequest, err := json.Marshal(initChatRequest)
	if err != nil {
		log.Print("Marshal Register information failed.")
		log.Fatal(err)
	}
	_, err = conn.WriteToUDP(jsonRequest, saddr)
	if err != nil {
		log.Fatal(err)
	}

	log.Print("Waiting for server response...")
	_, _, err = conn.ReadFromUDP(buf)
	if err != nil {
		log.Print("Register to server failed.")
		log.Fatal(err)
	}

	// Send connect request to server
	connectChatRequest := ChatRequest{
		"Get",
		username,
		peer,
	}
	jsonRequest, err = json.Marshal(connectChatRequest)
	if err != nil {
		log.Print("Marshal connection information failed.")
		log.Fatal(err)
	}

	var serverResponse ChatRequest
	for i := 0; i < 3; i++ {
		conn.WriteToUDP(jsonRequest, saddr)
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			log.Print("Get peer address from server failed.")
			log.Fatal(err)
		}
		err = json.Unmarshal(buf[:n], &serverResponse)
		if err != nil {
			log.Print("Unmarshal server response failed.")
			log.Fatal(err)
		}
		if serverResponse.Message != "" {
			break
		}
		time.Sleep(10 * time.Second)
	}
	if serverResponse.Message == "" {
		log.Fatal("Cannot get peer's address")
	}
	log.Print("Peer address: ", serverResponse.Message)
	peerAddr, err := net.ResolveUDPAddr("udp4", serverResponse.Message)
	if err != nil {
		log.Print("Resolve peer address failed.")
		log.Fatal(err)
	}

	// Start chatting.
	go listen(conn)
	for {
		fmt.Print("Input message: ")
		message := make([]byte, 2048)
		fmt.Scanln(&message)
		messageRequest := ChatRequest{
			"Chat",
			username,
			string(message),
		}
		jsonRequest, err = json.Marshal(messageRequest)
		if err != nil {
			log.Print("Error: ", err)
			continue
		}
		conn.WriteToUDP(jsonRequest, peerAddr)
	}
}

func listen(conn *net.UDPConn) {
	for {
		buf := make([]byte, 2048)
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			log.Print(err)
			continue
		}
		// log.Print("Message from ", addr.IP)

		var message ChatRequest
		err = json.Unmarshal(buf[:n], &message)
		if err != nil {
			log.Print(err)
			continue
		}
		fmt.Println(message.Username, ":", message.Message)
	}
}

golang 去我的博客文章中间件样本。 http://justinas.org/writing-http-middleware-in-go/

package main

import (
	"net/http"
	"net/http/httptest"
)

type ModifierMiddleware struct {
	handler http.Handler
}

func (m *ModifierMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	rec := httptest.NewRecorder()
	// passing a ResponseRecorder instead of the original RW
	m.handler.ServeHTTP(rec, r)
	// after this finishes, we have the response recorded
	// and can modify it before copying it to the original RW

	// we copy the original headers first
	for k, v := range rec.Header() {
		w.Header()[k] = v
	}
	// and set an additional one
	w.Header().Set("X-We-Modified-This", "Yup")
	// only then the status code, as this call writes the headers as well 
	w.WriteHeader(418)
        // The body hasn't been written (to the real RW) yet,
        // so we can prepend some data.
        data := []byte("Middleware says hello again. ")

        // But the Content-Length might have been set already,
        // we should modify it by adding the length
        // of our own data.
        // Ignoring the error is fine here:
        // if Content-Length is empty or otherwise invalid,
        // Atoi() will return zero,
        // which is just what we'd want in that case.
        clen, _ := strconv.Atoi(r.Header.Get("Content-Length"))
        clen += len(data)
        w.Header.Set("Content-Length", strconv.Itoa(clen))

        // finally, write out our data
        w.Write(data)
	// then write out the original body
	w.Write(rec.Body.Bytes())
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	mid := &ModifierMiddleware{http.HandlerFunc(myHandler)}

	println("Listening on port 8080")
	http.ListenAndServe(":8080", mid)
}
package main

import (
	"net/http"
)

type AppendMiddleware struct {
	handler http.Handler
}

func (a *AppendMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	a.handler.ServeHTTP(w, r)
	w.Write([]byte("<!-- Middleware says hello! -->"))
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	mid := &AppendMiddleware{http.HandlerFunc(myHandler)}

	println("Listening on port 8080")
	http.ListenAndServe(":8080", mid)
}
package main

import (
	"net/http"
)

func SingleHost(handler http.Handler, allowedHost string) http.Handler {
	ourFunc := func(w http.ResponseWriter, r *http.Request) {
		host := r.Host
		if host == allowedHost {
			handler.ServeHTTP(w, r)
		} else {
			w.WriteHeader(403)
		}
	}
	return http.HandlerFunc(ourFunc)
}


func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	single := SingleHost(http.HandlerFunc(myHandler), "example.com")

	println("Listening on port 8080")
	http.ListenAndServe(":8080", single)
}
package main

import (
	"net/http"
)

type SingleHost struct {
	handler     http.Handler
	allowedHost string
}

func NewSingleHost(handler http.Handler, allowedHost string) *SingleHost {
	return &SingleHost{handler: handler, allowedHost: allowedHost}
}

func (s *SingleHost) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	host := r.Host
	if host == s.allowedHost {
		s.handler.ServeHTTP(w, r)
	} else {
		w.WriteHeader(403)
	}
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	single := NewSingleHost(http.HandlerFunc(myHandler), "example.com")

	println("Listening on port 8080")
	http.ListenAndServe(":8080", single)
}

以上是关于golang Go中的虚拟UDP孔冲孔样本的主要内容,如果未能解决你的问题,请参考以下文章

golang go中的样本整数struct容器

Go 中的 UDP 服务器和客户端

Golang✔️走进 Go 语言✔️ 第二十三课 UDP & TCP

Golang✔️走进 Go 语言✔️ 第二十三课 UDP & TCP

golang 去我的博客文章中间件样本。 http://justinas.org/writing-http-middleware-in-go/

golang 去我的博客文章中间件样本。 http://justinas.org/writing-http-middleware-in-go/