Created
September 7, 2023 07:24
-
-
Save jreisinger/37c7524f220a161f0819749ff1968dae to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Chat is a TCP server that connects couples so they can talk. | |
// Adapted from https://go.dev/talks/2012/chat.slide | |
package main | |
import ( | |
"fmt" | |
"io" | |
"log" | |
"net" | |
) | |
const addr = ":1234" | |
func main() { | |
ln, err := net.Listen("tcp", addr) | |
if err != nil { | |
log.Fatal(err) | |
} | |
for { | |
conn, err := ln.Accept() | |
if err != nil { | |
log.Print(err) | |
continue | |
} | |
go match(conn) | |
} | |
} | |
var partner = make(chan io.ReadWriteCloser) | |
// match simultaneously tries to send and receive a connection on a channel. | |
func match(conn net.Conn) { | |
log.Printf("connection from %s", conn.RemoteAddr()) | |
fmt.Fprint(conn, "Waiting for a partner...") | |
select { | |
case partner <- conn: | |
// now handled by the other goroutine | |
case p := <-partner: | |
// start chat session between the two connections | |
chat(p, conn) | |
} | |
} | |
// chat copies data between the two connections. | |
func chat(a, b io.ReadWriteCloser) { | |
fmt.Fprintln(a, "Found one! Say hi.") | |
fmt.Fprintln(b, "Found one! Say hi.") | |
errc := make(chan error, 1) | |
go cp(a, b, errc) | |
go cp(b, a, errc) | |
if err := <-errc; err != nil { | |
log.Print(err) | |
} | |
a.Close() | |
b.Close() | |
} | |
// cp copies data with error handling. | |
func cp(w io.Writer, r io.Reader, errc chan<- error) { | |
_, err := io.Copy(w, r) | |
errc <- err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment