net包練習
//server.go
package main
import (
"bufio"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
"strings"
)
//這裏的獨寫用的是小文件 如果文件較大適合用bufio 或者read 分批次字節切片讀取
var (
binPath string
dirPath string
defaultFileName string
file404 string
file500 string
)
func Header(conn net.Conn) {
defer func() {
conn.Close()
fmt.Println("client closed",conn.RemoteAddr())
}()
fmt.Println("Client Connected:",conn.RemoteAddr())
//處理客戶端數據
reader := bufio.NewReader(conn)
//讀取數據
line,err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
}else {
//正常處理
nodes := strings.Fields(line)
//獲取請求資源(本地)路徑
path := filepath.Join(dirPath,nodes[1])
//如果請求路徑報錯的話 判斷
if info,err := os.Stat(path);err != nil {
//不存在 返回404的路徑
if os.IsNotExist(err){
path = file404
//不是因爲不存在報錯返回500
}else {
path = file500
}
}else {
//判斷請求路徑存在的話是目錄還是文件
//是目錄默認返回index.html
if info.IsDir(){
path = filepath.Join(path,defaultFileName)
}
////是文件就直接返回
}
//再次對path進行檢查(404.html/500.html/index.html)
if _,err := os.Stat(path);err == nil {
//fprint 寫入文件
fmt.Fprint(conn,"HTTP/1.1 %v 200 OK\r\n")
fmt.Fprint(conn,"Server:aaserver \r\n")
fmt.Fprint(conn,"\r\n")
bytes,_ := ioutil.ReadFile(path)
conn.Write(bytes)
}else {
fmt.Println(err)
}
}
}
func main() {
//獲取當前運行文件的路徑
binPath,_ = filepath.Abs(os.Args[0])
//獲取父目錄
dirPath = filepath.Dir(binPath)
//默認路徑
defaultFileName = "index.html"
//錯誤路徑
file404 = filepath.Join(dirPath,"404.html")
file500 = filepath.Join(dirPath,"500.html")
addr := ":9999"
//監聽端口
listener,err := net.Listen("tcp",addr)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
//延遲關閉
defer listener.Close()
fmt.Println("Listen on",listener.Addr())
for {
//獲取請求
conn,err := listener.Accept()
if err != nil {
fmt.Println(err)
continue
}
//用例程可以實現多併發處理請求
go Header(conn)
}
}
//client.go
package main
import (
"bufio"
"fmt"
"io"
"net"
"os"
)
func main() {
addr := "127.0.0.1:9999"
url := "/once.go"
client,err := net.Dial("tcp",addr)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
fmt.Fprintf(client,"Get %s HTTP/1.0\r\n",url)
reader := bufio.NewReader(client)
line,err := reader.ReadString('\n')
fmt.Println("請求行:")
fmt.Println("\t",line)
fmt.Println("請求頭:")
for {
line,err := reader.ReadString('\n')
if err != nil {
if err != io.EOF{
fmt.Println(err)
}
break
}
if line == "\r\n" {
break
}
//因爲line就自帶換行所以用print打印
fmt.Print("\t",line)
}
fmt.Println("響應體:")
for {
line, err := reader.ReadString('\n')
if err != nil {
if err != io.EOF {
fmt.Println(err)
}
break
}
if line == "\r\n" {
break
}
//因爲line就自帶換行所以用print打印
fmt.Print("\t", line)
}
client.Close()
}