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 语言✔️ 第二十三课 UDP & TCP
Golang✔️走进 Go 语言✔️ 第二十三课 UDP & TCP
golang 去我的博客文章中间件样本。 http://justinas.org/writing-http-middleware-in-go/
golang 去我的博客文章中间件样本。 http://justinas.org/writing-http-middleware-in-go/