go語言中net包tcp socket的使用


一、通過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);
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM