Server
檔案:main.go
package main
import (
"log"
)
func init() {
log.SetFlags(log.Lshortfile)
}
var (
addr = ":7001"
)
func main() {
log.Println("running on:", addr)
err := NewServer(addr).Listen()
if nil != err {
log.Fatal(err)
}
}
檔案:server.go
package main
import (
"bufio"
"log"
"net"
"strings"
)
type Server struct {
addr string
}
func NewServer(addr string) *Server {
return &Server{addr}
}
func (s *Server) Listen() error {
l, err := net.Listen("tcp", s.addr)
if nil != err {
log.Fatalln(err)
}
for {
conn, err := l.Accept()
if nil != err {
log.Println(err)
return err
}
log.Println("one client came")
session, err := s.handleLogin(conn)
if nil != err {
log.Println(err)
return err
}
session.Start()
}
return nil
}
func (s *Server) handleLogin(conn net.Conn) (*Session, error) {
userName, err := bufio.NewReader(conn).ReadString('\n')
if nil != err {
log.Println(err)
return nil, err
}
_, err = conn.Write([]byte("hi " + userName))
if nil != err {
log.Println(err)
return nil, err
}
session := &Session{
UserName: strings.TrimRight(userName, "\n"),
Conn: conn,
}
defaultSessionManager.AddSession(session)
return session, nil
}
檔案:session_manager.go
package main
var (
defaultSessionManager = &SessionManager{
Sessions: map[string]*Session{},
}
)
type SessionManager struct {
Sessions map[string]*Session
}
func (sm *SessionManager) AddSession(s *Session) {
sm.Sessions[s.UserName] = s
}
func (sm *SessionManager) GetSession(userName string) *Session {
return sm.Sessions[userName]
}
檔案:session.go
package main
import (
"bufio"
"log"
"net"
"strings"
)
type Session struct {
Conn net.Conn
UserName string
}
func NewSession(name string, conn net.Conn) *Session {
return &Session{
Conn: conn,
UserName: name,
}
}
func (s *Session) Start() {
go s.readloop()
}
func (s *Session) Send(b []byte) (int, error) {
return s.Conn.Write(b)
}
func (s *Session) Read(b []byte) (int, error) {
return s.Conn.Read(b)
}
func (s *Session) readloop() {
reader := bufio.NewReader(s.Conn)
for {
rec, err := reader.ReadString('\n')
if nil != err {
log.Println(err)
return
}
baz := strings.Split(rec, "#")
if 2 != len(baz) {
log.Println("wrong msg format")
return
}
userName := baz[0]
msg := baz[1]
_, err = defaultSessionManager.GetSession(userName).Send([]byte(s.UserName + ": " + msg))
if nil != err {
log.Println(err)
return
}
}
}
Client
檔案:client.go
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func init() {
log.SetFlags(log.Lshortfile)
}
type Client struct {
addr string
Conn net.Conn
}
func NewClient(addr string) *Client {
return &Client{addr: addr}
}
func (s *Client) Run() {
conn, err := net.Dial("tcp", s.addr)
if nil != err {
log.Fatalln(err)
}
s.Conn = conn
err = s.login()
if nil != err {
log.Fatal(err)
}
go s.writeloop()
s.readloop()
}
func (s *Client) login() error {
_, err := s.Conn.Write([]byte(*userName + "\n"))
if nil != err {
log.Println(err)
return err
}
return nil
}
func (s *Client) readloop() error {
for {
bin := make([]byte, 10, 10)
n, err := s.Conn.Read(bin)
if nil != err {
log.Println(err)
err = s.Conn.Close()
if nil != err {
log.Println(err)
return err
}
return err
}
fmt.Print(string(bin[:n]))
}
return nil
}
func (s *Client) writeloop() error {
reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if nil != err {
log.Println(err)
return err
}
_, err = s.Conn.Write([]byte(input))
if nil != err {
log.Println(err)
err = s.Conn.Close()
if nil != err {
log.Println(err)
return err
}
return err
}
}
return nil
}
檔案:main.go
package main
import (
"flag"
"log"
)
var (
addr = ":7001"
)
var (
userName = flag.String("name", "", "user name")
)
func init() {
flag.Parse()
}
func main() {
if "" == *userName {
log.Fatal("input your name")
}
NewClient(addr).Run()
}
https://github.com/elvin-du/dim