一、通過socket我們模擬請求網易
package main;
import (
"net"
"log"
"io/ioutil"
"fmt"
)
func chkError(err error) {
if err != nil {
log.Fatal(err);
}
}
func main() {
//我們模擬請求網易的服務器
//ResolveTCPAddr用於獲取一個TCPAddr
//net參數是"tcp4"、"tcp6"、"tcp"
//addr表示域名或IP地址加端口號
tcpaddr, err := net.ResolveTCPAddr("tcp4", "www.163.com:80");
chkError(err);
//DialTCP建立一個TCP連接
//net參數是"tcp4"、"tcp6"、"tcp"
//laddr表示本機地址,一般設為nil
//raddr表示遠程地址
tcpconn, err2 := net.DialTCP("tcp", nil, tcpaddr);
chkError(err2);
//向tcpconn中寫入數據
_, err3 := tcpconn.Write([]byte("GET / HTTP/1.1 \r\n\r\n"));
chkError(err3);
//讀取tcpconn中的所有數據
data, err4 := ioutil.ReadAll(tcpconn);
chkError(err4);
//打印出數據
fmt.Println(string(data));
}

二、通過socket創建簡單的服務端
package main;
import (
"net"
"log"
)
func chkError(err error) {
if err != nil {
log.Fatal(err);
}
}
func main() {
//創建一個TCP服務端
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
//監聽端口
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
//死循環的處理客戶端請求
for {
//等待客戶的連接
//注意這里是無法並發處理多個請求的
conn, err3 := tcplisten.Accept();
//如果有錯誤直接跳過
if err3 != nil {
continue;
}
//向客戶端發送數據,並關閉連接
conn.Write([]byte("hello,client \r\n"));
conn.Close();
}
}

通過xshell的telnet方法測試。
三、改進上面的代碼,使用goroutine來處理用戶的請求
package main;
import (
"log"
"net"
"time"
)
func chkError(err error) {
if err != nil {
log.Fatal(err);
}
}
//單獨處理客戶端的請求
func clientHandle(conn net.Conn) {
defer conn.Close();
conn.Write([]byte("hello " + time.Now().String()));
}
func main() {
//創建一個TCP服務端
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
//監聽端口
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
//死循環的處理客戶端請求
for {
//等待客戶的連接
conn, err3 := tcplisten.Accept();
//如果有錯誤直接跳過
if err3 != nil {
continue;
}
//通過goroutine來處理用戶的請求
go clientHandle(conn);
}
}

四、連續的處理客戶端發送的請求,根據cmd命令不同,返回不同數據。
package main;
import (
"net"
"time"
"log"
"strings"
)
func chkError(err error) {
if err != nil {
log.Fatal(err);
}
}
//單獨處理客戶端的請求
func clientHandle(conn net.Conn) {
//設置當客戶端3分鍾內無數據請求時,自動關閉conn
conn.SetReadDeadline(time.Now().Add(time.Minute * 3));
defer conn.Close();
//循環的處理客戶的請求
for {
data := make([]byte, 256);
//從conn中讀取數據
n, err := conn.Read(data);
//如果讀取數據大小為0或出錯則退出
if n == 0 || err != nil {
break;
}
//去掉兩端空白字符
cmd := strings.TrimSpace(string(data[0:n]));
//發送給客戶端的數據
rep := "";
if(cmd == "string") {
rep = "hello,client \r\n";
} else if (cmd == "time") {
rep = time.Now().Format("2006-01-02 15:04:05");
}
//發送數據
conn.Write([]byte(rep));
}
}
func main() {
tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
chkError(err);
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
chkError(err2);
for {
conn, err3 := tcplisten.Accept();
if err3 != nil {
continue;
}
go clientHandle(conn);
}
}

