注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

记录创意的火花

天天学习,好好向上

 
 
 

日志

 
 

三个版本的 ECHO Server for Golang  

2014-10-18 17:46:28|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
////////////////////////////////////////第一个版本///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main

import (
"net"
"fmt"
"os"
)


func main() {

lsr, err := net.Listen("tcp", ":5555")

if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
return
}
for {
conn , err := lsr.Accept()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
continue
}

go connHandler(conn)

}

fmt.Println("Done !")
}

func connHandler(conn net.Conn) {
defer conn.Close()

var buf[512]byte
for {
n , err := conn.Read(buf[0:])
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
return
}
_, err = conn.Write(buf[0:n])
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
return
}
}
}
//////////////////////////////////////////////////////////////////第二个版本///////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main

import (
"fmt";
"net";
"os";
// "runtime";
)

type tcpPacket struct {
     data string;
     con net.Conn;
}

func handle(packet tcpPacket) {
     // just echo
     packet.con.Write([]byte(packet.data));
     //fmt.Println("Packet: ", packet);
   //  fmt.Printf("From socket: %w  data: '%s'\n", packet.con, packet.data);
}

func main() {
     fmt.Println("Initiating server... (Ctrl-C to stop)");
     var (
host = "0.0.0.0";
port = "5555";
laddr = host + ":" + port;
)
//runtime.GOMAXPROCS(runtime.NumCPU())

     data_ch := make(chan tcpPacket);
     go listen(data_ch, laddr);
     for {
go handle( <- data_ch );
     }
}

func listen(data_ch chan tcpPacket, laddr string) {
     fmt.Println("Listen started");
     lis, error := net.Listen("tcp", laddr);
     defer lis.Close();
     if error != nil {
fmt.Printf("Error creating listener: %s\n", error );
os.Exit(1);
     }
     for {
con, error := lis.Accept();
if error != nil { fmt.Printf("Error: Accepting data: %s\n", error); os.Exit(2); }
go listen_socket(data_ch, con);
     }
}

func listen_socket(data_ch chan tcpPacket, con net.Conn) {
     fmt.Printf("=== New Connection received from: %s \n", con.RemoteAddr());
     data   := make([]byte, 16);
     defer con.Close();
     for {
n, error := con.Read(data[0:]);
switch error {
     case nil:
  packet := tcpPacket{ string(data[0:n]), con };
  data_ch <- packet;
    
     default:
  fmt.Printf("Error: Reading data : %s \n", error);
  return;
         }
     }
}
 /////////////////////////////////////////////////////第三个版本/////////////////////////////////////////////////////////////////////////////////////////////////////////

package main

import (
    "fmt"
    "net"
    "os"
    "time"
)

//echo server Goroutine
func EchoFunc(conn net.Conn) {
    defer conn.Close()
    buf := make([]byte, 1024)
    for {
        _, err := conn.Read(buf)
        if err != nil {
            //println("Error reading:", err.Error())
            return
        }
        //send reply
        _, err = conn.Write(buf)
        if err != nil {
            //println("Error send reply:", err.Error())
            return
        }
    }
}

//initial listener and run
func main() {
    listener, err := net.Listen("tcp", "0.0.0.0:5555")
    if err != nil {
        fmt.Println("error listening:", err.Error())
        os.Exit(1)
    }
    defer listener.Close()

    fmt.Printf("running ...\n")

    var cur_conn_num int = 0
    conn_chan := make(chan net.Conn)
    ch_conn_change := make(chan int)

    go func() {
        for conn_change := range ch_conn_change {
            cur_conn_num += conn_change
        }
    }()

    go func() {
        for _ = range time.Tick(1e8) {
            fmt.Printf("cur conn num: %f\n", cur_conn_num)
        }
    }()

    for {
        conn, err := listener.Accept()
        if err != nil {
            println("Error accept:", err.Error())
            return
        }

        go func() {
            for conn := range conn_chan {
                ch_conn_change <- 1
                EchoFunc(conn)
                ch_conn_change <- -1
            }
        }()

        conn_chan <- conn

    }
}
三个版本的运行效果差距巨大,从此例看golang 并行编程
  评论这张
 
阅读(617)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017