golang代码片段(摘抄)

以下是从golang并发编程实战2中摘抄过来的代码片段,主要是实现一个简单的tcp socket通讯(客户端发送一个数字,服务端计算该数字的立方根然后返回),写的不错,用到了go的并发以及看下郝林大神是如何处理socket通讯的。具体代码记录如下,多看多学习多共勉:

package main

import (
	"net"
	"strings"
	"fmt"
	"time"
	"io"
	"bytes"
	"strconv"
	"math"
	"math/rand"
	"sync"
)
const (
	SERVER_NETWORK = "tcp"
	SERVER_ADDRESS = "127.0.0.1:8085"
	DELIMITER = ‘\t‘
)

var wg sync.WaitGroup

func main() {
	wg.Add(2)
	go serverGo()
	time.Sleep(500 * time.Millisecond)
	go clientGo(1)
	wg.Wait()
}

func serverGo() {
	defer wg.Done()
	listener, err := net.Listen(SERVER_NETWORK, SERVER_ADDRESS)
	if err != nil {
		printServerLog("Listen Error: %s", err)
		return
	}
	defer listener.Close()
	printServerLog("Got listener for the server.(local address: %s)", listener.Addr())
	for {
		conn, err := listener.Accept()
		if err != nil {
			printServerLog("Accept Error: %s", err)
		}
		printServerLog("Established a connection with a client application,(remote address: %s)", conn.RemoteAddr())
		go handleConn(conn)
	}
}

func printLog(role string, sn int, format string, args ...interface{})  {
	if !strings.HasSuffix(format, "\n") {
		format += "\n"
	}
	fmt.Printf("%s[%d]: %s", role, sn, fmt.Sprintf(format, args...))
}

func printServerLog(format string, args ...interface{})  {
	printLog("Server", 0, format, args...)
}

func printClientLog(sn int, format string, args ...interface{})  {
	printLog("Cient", sn, format, args...)
}

func handleConn(conn net.Conn)  {
	defer conn.Close()
	for {
		conn.SetDeadline(time.Now().Add(10 * time.Second))		// set read timeline 10s
		strReq, err := read(conn)
		if err != nil {
			if err == io.EOF {
				printServerLog("The connection is closed by another side.")
			} else {
				printServerLog("Read Error: %s", err)
			}
			break
		}
		printServerLog("Received request: %s", strReq)
		intReq, err := strToInt32(strReq)
		if err != nil {
			n, err := write(conn, err.Error())
			printServerLog("Sent error message (written %d bytes): %s", n, err)
			continue
		}
		floatResp := cbrt(intReq)
		respMsg := fmt.Sprintf("The cube root of %d is %f.", intReq, floatResp)
		n, err := write(conn, respMsg)
		if err != nil {
			printServerLog("Sent response message (written %d bytes: %s).", n, respMsg)
		}
	}
}

func read(conn net.Conn) (string, error){
	readBytes := make([]byte, 1)
	var buffer bytes.Buffer
	for {
		_, err := conn.Read(readBytes)
		if err != nil {
			return "", err
		}
		readByte := readBytes[0]
		if readByte == DELIMITER {
			break
		}
		buffer.WriteByte(readByte)
	}
	return buffer.String(), nil
}

func strToInt32(str string) (int32, error){
	i32, err := strconv.ParseInt(str, 10 ,32)
	return int32(i32), err
}

func write(conn net.Conn, content string) (int, error) {
	var buffer bytes.Buffer
	buffer.WriteString(content)
	buffer.WriteByte(DELIMITER)
	return conn.Write(buffer.Bytes())
}

func cbrt(intReq int32) float64 {
	return math.Cbrt(float64(intReq))
}

func clientGo(id int)  {
	defer wg.Done()
	conn, err := net.DialTimeout(SERVER_NETWORK, SERVER_ADDRESS, 2 * time.Second)
	if err != nil {
		printClientLog(id, "Dial Error: %s", err)
		return
	}
	defer conn.Close()
	printClientLog(id, "Connected to server.(remote address: %s,local address: %s)", conn.RemoteAddr(), conn.LocalAddr())
	time.Sleep(200 * time.Millisecond)

	requestNumber := 5
	conn.SetDeadline(time.Now().Add(5 * time.Millisecond))
	for i := 0; i< requestNumber; i++ {
		req := rand.Int31()
		n, err := write(conn, fmt.Sprintf("%d", req))
		if err != nil {
			printClientLog(id, "Write Error: %s", err)
			continue
		}
		printClientLog(id, "Sent request (written %d bytes)", n)
	}
	for j := 0; j< requestNumber; j++ {
		strResp, err := read(conn)
		if err != nil {
			if err == io.EOF {
				printClientLog(id, "The connection is closed by another side.")
			}else{
				printClientLog(id, "Read Error: %s", err)
			}
			break
		}
		printClientLog(id, "Received response: %s", strResp)
	}
}

执行效果:

时间: 2024-10-24 21:01:41

golang代码片段(摘抄)的相关文章

solr分布式索引【实战一、分片配置读取:工具类configUtil.java,读取配置代码片段,配置实例】

1 private static Properties prop = new Properties(); 2 3 private static String confFilePath = "conf" + File.separator + "config.properties";// 配置文件目录 4 static { 5 // 加载properties 6 InputStream is = null; 7 InputStreamReader isr = null;

100个直接可以拿来用的JavaScript实用功能代码片段

把平时网站上常用的一些实用功能代码片段通通收集起来,方面网友们学习使用,利用好的话可以加快网友们的开发速度,提高工作效率. 目录如下: 1.原生JavaScript实现字符串长度截取2.原生JavaScript获取域名主机3.原生JavaScript清除空格4.原生JavaScript替换全部5.原生JavaScript转义html标签6.原生JavaScript还原html标签7.原生JavaScript时间日期格式转换8.原生JavaScript判断是否为数字类型9.原生JavaScript

关于UITabBar各部分自定义的代码片段

一.自定义TabBar选项卡背景默认UITabBarController的TabBar背景是黑色的,如何自定义成背景图片呢? UITabBarController *tabBarController = [[UITabBarController alloc] init]; // 获取选项卡控制器视图的所有子视图,保存到一数组中 NSArray *array = [tabBarController.view subviews]; // 索引值为1的应该就是TabBar UITabBar  *tab

常用python日期、日志、获取内容循环的代码片段

近段时间对shell脚本和python进行了梳理,将一些脚本中常用的内容,考虑多种方法整理出来,形成有用的代码片段,这样就可以在需要的时候直接使用,也可以用于备忘和思考.本次整理的代码片段有: python中日期.时间常用获取方法: 记录处理日志的logging模块使用:从目录,文件,命名结果中,获取循环条件进行循环.我将这些有用的代码片段整理在一个Python脚本中了,并且测试可用.脚本内容如下: #!/usr/bin/env python #_*_coding:utf8_*_ #常用日期和时

sublime text3 之snippet编写代码片段

sublime text 3 中有个强大的功能就是可以编写各种文件类型的snippet代码片段,可以节省大量的时间. 文件名为:jekyll-top.sublime-snippet(.sublime-snippet)后缀必须这样 <snippet> <content><![CDATA[/** * author:qinbb * title:智能推荐${1:标题} */ ${2}]]></content> <!-- Optional: Set a tabT

Sublime Text Snippets(代码片段)功能

我们在编写代码的时候,总会遇到一些需要反复使用的代码片段.这时候就需要反复的复制和黏贴,大大影响效率.我们利用Sublime Text的snippet功能,就能很好的解决这一问题.通俗的讲,就是把我们常用的代码分别保存起啦,然后通过插件的形式来反复调用. 创建方法:Tools > New Snippet 这时你会看到如下示例代码: 1 <snippet> 2 <content><![CDATA[ 3 Hello, ${1:this} is a ${2:snippet}.

xcode自动生成代码片段

一.什么是代码片段 当在Xcode中输入dowhile并回车后,Xcode会出现下图所示的提示代码: 这就是代码片段,目的是使程序员以最快的速度输入常用的代码片段,提高编程效率.该功能是从Xcode4开始引入的.在Xcode中的位置如下图所示: 里面有很多Xcode自带的代码片段,上例中的dowhile就是其中的一个. 二.如何自定义代码片段 由于项目.所用语言或者编码习惯的差别,不同的程序员习惯用的代码片段也不尽相同,这就有了自定义代码片段的需求,好在Xcode是支持该功能的. @proper

10个常用的JQUERY代码片段

jQuery被用在无数个网站的页面上,它是使用最为广泛的javascript库之一.jQuery的受欢迎程度的部分是它的简单性.它能够通过简单的语句完成大部分复杂的工作.有许多jQuery片段我们在每天不断重复的使用,这里总结了10条你必须知道的jQuery代码片段. 返回顶部 <a class="top" href="#">Back to top</a> // Back To Top $('a.top').click(function(){

sublime text 2自定义代码片段

本文引用   http://www.blogjava.net/Hafeyang/archive/2012/08/17/how_to_create_code_snippet_in_subline_text_2.html 对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点击Tools -> New Snippet,(工具->代码段)会新建一个xml文