我们写了一个简单的“ping-pong”客户端和服务器分别用go语言
09 |
func
handleClient(conn net.Conn) { |
14 |
n,
err := conn.Read(buf[0:]) |
17 |
_,
err = conn.Write([]byte( "Pong" )) |
26 |
tcpAddr,
_ := net.ResolveTCPAddr( "tcp4" , ":1201" ) |
27 |
listener,
_ := net.ListenTCP( "tcp" ,
tcpAddr) |
30 |
conn,
_ := listener.Accept() |
11 |
func
ping(times int ,
lockChan chan bool )
{ |
12 |
tcpAddr,
_ := net.ResolveTCPAddr( "tcp4" , "localhost:1201" ) |
13 |
conn,
_ := net.DialTCP( "tcp" ,
nil, tcpAddr) |
15 |
for i:=0;
i< int (times);
i++ { |
16 |
_,
_ = conn.Write([]byte( "Ping" )) |
18 |
_,
_ = conn.Read(buff[0:]) |
27 |
var
totalPings int =
1000000 |
28 |
var
concurrentConnections int =
100 |
29 |
var
pingsPerConnection int =
totalPings/concurrentConnections |
30 |
var
actualTotalPings int =
pingsPerConnection*concurrentConnections |
32 |
lockChan
:= make(chan bool ,
concurrentConnections) |
35 |
for i:=0;
i<concurrentConnections; i++{ |
36 |
go
ping(pingsPerConnection, lockChan) |
38 |
for i:=0;
i< int (concurrentConnections);
i++{ |
41 |
elapsed
:= 1000000* time .Since(start).Seconds() |
42 |
fmt.Println(elapsed/float64(actualTotalPings)) |
和Scala语言
03 |
import scala.concurrent.ExecutionContext.Implicits.global |
04 |
import scala.concurrent. _ |
08 |
def handleClient(s : Socket) : Unit = { |
09 |
val in = s.getInputStream |
10 |
val out = s.getOutputStream |
12 |
val buffer = Array[Byte]( 4 ) |
14 |
out.write( "Pong" .getBytes) |
18 |
def main(args : Array[String]){ |
19 |
val server = new ServerSocket( 1201 ) |
21 |
val s : Socket = server.accept() |
22 |
future
{ handleClient(s) } |
02 |
import scala.concurrent. _ |
03 |
import scala.concurrent.duration. _ |
04 |
import scala.concurrent.ExecutionContext.Implicits.global |
09 |
def ping(timesToPing : Int) : Unit = { |
10 |
val socket = new Socket( "localhost" , 1201 ) |
11 |
val out = socket.getOutputStream |
12 |
val in = socket.getInputStream |
13 |
for (i
<- 0 until
timesToPing) { |
14 |
out.write( "Ping" .getBytes) |
15 |
val buffer = Array[Byte]( 4 ) |
21 |
def main(args : Array[String]){ |
22 |
var totalPings = 1000000 |
23 |
var concurrentConnections = 100 |
24 |
var pingsPerConnection : Int = totalPings/concurrentConnections |
25 |
var actualTotalPings : Int = pingsPerConnection*concurrentConnections |
27 |
val t 0 = (System.currentTimeMillis()).toDouble |
28 |
var futures = ( 0 until
concurrentConnections).map{ _ = > |
29 |
future(ping(pingsPerConnection)) |
32 |
Await.result(Future.sequence(futures), 1 minutes) |
33 |
val t 1 = (System.currentTimeMillis()).toDouble |
34 |
println( 1000 *(t 1 -t 0 )/actualTotalPings) |
后者和 WebSockets vs. TCP benchmark一文中用到的完全一致。两者操作都很简单并有提升的空间。实际的测试代码中包括的功能性测试能处理一些连接错误,此处省略不作赘述。
客户端想服务器发出一系列持久并发的连接请求并且发送一定数量的ping(即字符串“Ping”)。服务器对每个“Ping”请求做出回应并回复“Pong”。
实验是在2.7G赫兹的四核苹果笔记本上演示的。客户端和服务器分别运行,以用来更好地测试程序运行的系统开销。
客户端能生成100个并发请求并发出100万次的ping到服务器端,并通过连接平均分布ping。我们测试了全程的“ping-pong”往返时间。