Last active
August 29, 2015 14:20
-
-
Save fourcube/2f6b29edcf600743a9dd to your computer and use it in GitHub Desktop.
Go Echo Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"log" | |
"net" | |
) | |
func EchoServer(addr string, done chan struct{}) net.Listener { | |
listener, err := net.Listen("tcp", addr) | |
if err != nil { | |
log.Fatalf("Error listening, %v ", err) | |
} | |
// This implementation does not block, but instead runs it's | |
// accept -> handle loop inside a goroutine | |
go func() { | |
for { | |
select { | |
// When the 'done' channel gets closed or receives | |
// the echo server's listener gets shut down | |
case <-done: | |
listener.Close() | |
return | |
default: | |
conn, err := listener.Accept() | |
if err != nil { | |
log.Printf("Error during accept, %v ", err) | |
return | |
} | |
// Do all the work inside a goroutine so we can quickly accept | |
// other connections | |
go handle(conn) | |
} | |
} | |
}() | |
return listener | |
} | |
func handle(client net.Conn) { | |
var err error | |
for err == nil { | |
// ...simply return everything the client sends to itself | |
_, err = io.Copy(client, client) | |
if err != nil && err != io.EOF { | |
log.Printf("Error during echo %v", err) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"net" | |
"testing" | |
) | |
func TestEchoServer(t *testing.T) { | |
done := make(chan struct{}) | |
echo := echoServer(":0", done) | |
conn, err := net.Dial("tcp", echo.Addr().String()) | |
if err != nil { | |
t.Errorf("Expected no error, got %v", err) | |
} | |
recv := make([]byte, 32) | |
conn.Write([]byte("foo")) | |
n, err := conn.Read(recv) | |
if err != nil { | |
t.Errorf("Expected no error, got %v", err) | |
} | |
data := string(recv[:n]) | |
if data != "foo" { | |
t.Errorf("Expected to receive 'foo', got %s", data) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment