Golang实现端口转发

package main

import (
	"io"
	"net"
)

func main() {
	server, err := net.Listen("tcp", ":8080")
	if err != nil {
		return
	}
	for {
		client, err := server.Accept()
		if err == nil {
			go handleClientRequest(client)
		}
	}
}

func handleClientRequest(client net.Conn) {
	defer client.Close()

	remote, err := net.Dial("tcp", "127.0.0.1:80")
	if err != nil {
		return
	}
	defer remote.Close()

	go io.Copy(remote, client)
	io.Copy(client, remote)
}

IP地址库解析


main();

function main(){
	$ip = isset($_GET["ip"]) ? $_GET["ip"] : "";

	if (empty($ip)) {
		IP::respone("101", "Empty IP");
		exit();
	}

	if (!preg_match("/(\d+\.){3}\d+/", $ip)) {
		IP::respone("102", "Wrong IP");
		exit();
	}

	$address = IP::find($ip);

	IP::respone("0", $address);
}

class IP {
	
    private static $ip     = NULL;
    private static $fp     = NULL;
    private static $offset = NULL;
    private static $index  = NULL;

    public static function find($ip)
    {
        if (empty($ip) === TRUE)
        {
            return "N/A";
        }

        $nip   = gethostbyname($ip);
        $ipdot = explode(".", $nip);

        if ($ipdot[0] < 0 || $ipdot[0] > 255 || count($ipdot) !== 4)
        {
            return "N/A";
        }

        if (self::$fp === NULL)
        {
            self::init();
        }

        $nip2 = pack("N", ip2long($nip));

        $tmp_offset = ((int)$ipdot[0] * 256 + (int)$ipdot[1]) * 4;
        $start      = unpack("Vlen", self::$index[$tmp_offset] . self::$index[$tmp_offset + 1] . self::$index[$tmp_offset + 2] . self::$index[$tmp_offset + 3]);

        $index_offset = $index_length = NULL;
        $max_comp_len = self::$offset["len"] - 262144 - 4;
        for ($start = $start["len"] * 9 + 262144; $start < $max_comp_len; $start += 9)
        {
            if (self::$index{$start} . self::$index{$start + 1} . self::$index{$start + 2} . self::$index{$start + 3} >= $nip2)
            {
                $index_offset = unpack("Vlen", self::$index{$start + 4} . self::$index{$start + 5} . self::$index{$start + 6} . "\x0");
                $index_length = unpack("nlen", self::$index{$start + 7} . self::$index{$start + 8});

                break;
            }
        }

        if ($index_offset === NULL)
        {
            return "N/A";
        }

        fseek(self::$fp, self::$offset["len"] + $index_offset["len"] - 262144);

        return explode("\t", fread(self::$fp, $index_length["len"]));
    }

    private static function init()
    {
        if (self::$fp === NULL)
        {
            self::$ip = new self();

            self::$fp = fopen(__DIR__ . "/ipdb.datx", "rb");
            if (self::$fp === FALSE)
            {
                throw new Exception("Invalid ipdb.datx file!");
            }

            self::$offset = unpack("Nlen", fread(self::$fp, 4));
            if (self::$offset["len"] < 4)
            {
                throw new Exception("Invalid ipdb.datx file!");
            }

            self::$index = fread(self::$fp, self::$offset["len"] - 4);
        }
    }

    public function __destruct()
    {
        if (self::$fp !== NULL)
        {
            fclose(self::$fp);

            self::$fp = NULL;
        }
    }

    public static function respone($code, $data){
        echo json_encode(["code" => $code, "data" => $data], JSON_UNESCAPED_UNICODE);
    }

}

Golang使用redis连接池


package main

import (
	"github.com/gin-gonic/gin"
	"github.com/gomodule/redigo/redis"
	"log"
)

var redisPool *redis.Pool
var err error

func main() {

	redisPool = RedisPollInit()

	gin.SetMode(gin.ReleaseMode)

	r := gin.Default()

	r.GET("/", IndexAction)

	r.GET("/ping", PingAction)

	r.GET("/user/:name", UserAction)

	r.GET("/agent", AgentAction)

	r.GET("/admin", AdminAction)

	r.Run(":80")

}

func RedisPollInit() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   3,
		MaxActive: 5,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", "127.0.0.1:6379")
			if err != nil {
				return nil, err
			}

			_, err = c.Do("AUTH", "123456")
			if err != nil {
				c.Close()
				return nil, err
			}
			return c, err
		},
	}
}

func IndexAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "index"})
}

func PingAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "pong"})
}

func UserAction(c *gin.Context) {
	c.String(200, "Hello %s", c.Param("name"))
}

func AgentAction(c *gin.Context) {
	c.String(200, c.GetHeader("user-agent"))
}

func AdminAction(c *gin.Context) {

	conn := redisPool.Get()
	defer conn.Close()

	data, err := redis.String(conn.Do("GET", "username"))
	if err != nil {
		log.Println(err)
		return
	}
	c.String(200, data)
}

Golang实现API


package main

import (
	"database/sql"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"log"
)

var db *sql.DB
var err error

func main() {

	DatabaseInit()

	gin.SetMode(gin.ReleaseMode)

	r := gin.Default()

	r.GET("/", IndexAction)

	r.GET("/ping", PingAction)

	r.GET("/user/:name", UserAction)

	r.GET("/agent", AgentAction)

	r.Run()
}

func DatabaseInit() {

	db, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/wordpress")
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()

	db.SetMaxIdleConns(20)
	db.SetMaxOpenConns(20)

	err = db.Ping()
	if err != nil {
		log.Fatalln(err)
	}

}

func IndexAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "index"})
}

func PingAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "pong"})
}

func UserAction(c *gin.Context) {
	c.String(200, "Hello %s", c.Param("name"))
}

func AgentAction(c *gin.Context) {
	c.String(200, c.GetHeader("user-agent"))
}

Golang使用数据库


package main

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"net/http"
)

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/" {
		w.Write([]byte("Index Page"))
	} else {
		w.Write([]byte("404"))
	}
}

func UserHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {

		var ID int
		var username, email string

		err := db.QueryRow("select ID, user_login, user_email from wp_users WHERE ID = 1").Scan(&ID, &username, &email)
		if err != nil {
			log.Print(err)
			return
		}

		w.Write([]byte(username))
	} else {
		w.Write([]byte("User Post"))
	}
}

var db *sql.DB
var err error

func main() {

	db, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/wordpress")
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()

	db.SetMaxIdleConns(20)
	db.SetMaxOpenConns(20)

	if err = db.Ping(); err != nil {
		log.Fatalln(err)
	}

	http.HandleFunc("/", IndexHandler)
	http.HandleFunc("/user", UserHandler)
	http.ListenAndServe(":8080", nil)
}

Golang之切片Slice

// 创建切片
var slice1 []int
slice2 := []string
slice3 := []byte{'g', 'o', 'o', 'g', 'l', 'e'}

// 添加元素
slice1 = append(slice1, 1)

Golang之Buffer缓冲器

// 创建 Buffer
import ""
var DataBuffer bytes.Buffer
var DataBuffer1 =  bytes.NewBuffer([]byte{})
var DataBuffer2 =  bytes.NewBufferString("abc")

// 写入数据
DataBuffer.Write([]byte("Hello"))
DataBuffer1.WriteString("Hello")
DataBuffer2.WriteByte([]byte("Hello"))

// 读取数据
DataBuffer.String()

CentOS远程重做系统

wget https://mirrors.aliyun.com/centos/6.9/os/x86_64/images/pxeboot/initrd.img
wget https://mirrors.aliyun.com/centos/6.9/os/x86_64/images/pxeboot/vmlinuz

mv vmlinuz /boot/vmlinuz.cent.pxe
mv initrd.img /boot/initrd.img.cent.pxe

vi /boot/grub/grub.conf

title Centos Install (PXE)
    root (hd0,0)
    kernel /boot/vmlinuz.cent.pxe
    initrd /boot/initrd.img.cent.pxe