利用tcp服務(wù)器和客戶端,創(chuàng)建一個(gè)聊天室

服務(wù)器

package main

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

var clients []net.Conn

func main() {
    var (
        host   = "localhost"
        port   = "8000"
        remote = host + ":" + port
        data   = make([]byte, 1024)
    )
    fmt.Println("Initiating server...")

    lis, err := net.Listen("tcp", remote)
    defer lis.Close()

    if err != nil {
        fmt.Printf("Error when listen: %s, Err: %s\n", remote, err)
        os.Exit(-1)
    }

    for {
        var res string
        conn, err := lis.Accept()
        if err != nil {
            fmt.Println("Error accepting client: ", err.Error())
            os.Exit(0)
        }
        clients = append(clients, conn)

        go func(con net.Conn) {
            fmt.Println("New connection: ", con.RemoteAddr())

            // Get client's name
            length, err := con.Read(data)
            if err != nil {
                fmt.Printf("Client %v quit.\n", con.RemoteAddr())
                con.Close()
                disconnect(con, con.RemoteAddr().String())
                return
            }
            name := string(data[:length])
            comeStr := name + " entered the room."
            notify(con, comeStr)

            // Begin recieve message from client
            for {
                length, err := con.Read(data)
                if err != nil {
                    fmt.Printf("Client %s quit.\n", name)
                    con.Close()
                    disconnect(con, name)
                    return
                }
                res = string(data[:length])
                sprdMsg := name + " said: " + res
                fmt.Println(sprdMsg)
                res = "You said:" + res
                con.Write([]byte(res))
                notify(con, sprdMsg)
            }
        }(conn)
    }
}


func notify(conn net.Conn, msg string) {
    for _, con := range clients {
        if con.RemoteAddr() != conn.RemoteAddr() {
            con.Write([]byte(msg))
        }
    }
}


func disconnect(conn net.Conn, name string) {
    for index, con := range clients {
        if con.RemoteAddr() == conn.RemoteAddr() {
            disMsg := name + " has left the room."
            fmt.Println(disMsg)
            clients = append(clients[:index], clients[index+1:]...)
            notify(conn, disMsg)
        }
    }
}

客戶端

package main

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

var writeStr, readStr = make([]byte, 1024), make([]byte, 1024)

func main() {
    var (
        host   = "localhost"
        port   = "8000"
        remote = host + ":" + port
        reader = bufio.NewReader(os.Stdin)
    )

    con, err := net.Dial("tcp", remote)
    defer con.Close()

    if err != nil {
        fmt.Println("Server not found.")
        os.Exit(-1)
    }
    fmt.Println("Connection OK.")
    fmt.Printf("Enter your name: ")
    fmt.Scanf("%s", &writeStr)
    in, err := con.Write([]byte(writeStr))
    if err != nil {
        fmt.Printf("Error when send to server: %d\n", in)
        os.Exit(0)
    }
    fmt.Println("Now begin to talk!")
    go read(con)

    for {
        writeStr, _, _ = reader.ReadLine()
        if string(writeStr) == "quit" {
            fmt.Println("Communication terminated.")
            os.Exit(1)
        }

        in, err := con.Write([]byte(writeStr))
        if err != nil {
            fmt.Printf("Error when send to server: %d\n", in)
            os.Exit(0)
        }

    }
}

func read(conn net.Conn) {
    for {
        length, err := conn.Read(readStr)
        if err != nil {
            fmt.Printf("Error when read from server. Error:%s\n", err)
            os.Exit(0)
        }
        fmt.Println(string(readStr[:length]))
    }
}

資料參考:http://blog.csdn.net/wangshubo1989/article/details/70668916

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末险掀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子湾宙,更是在濱河造成了極大的恐慌樟氢,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侠鳄,死亡現(xiàn)場(chǎng)離奇詭異埠啃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伟恶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門碴开,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人博秫,你說我怎么就攤上這事叹螟【槁睿” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵罢绽,是天一觀的道長(zhǎng)畏线。 經(jīng)常有香客問我,道長(zhǎng)良价,這世上最難降的妖魔是什么寝殴? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮明垢,結(jié)果婚禮上蚣常,老公的妹妹穿的比我還像新娘。我一直安慰自己痊银,他們只是感情好抵蚊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溯革,像睡著了一般贞绳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上致稀,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天冈闭,我揣著相機(jī)與錄音,去河邊找鬼抖单。 笑死萎攒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的矛绘。 我是一名探鬼主播耍休,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼货矮!你這毒婦竟也來了羊精?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤次屠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后雳刺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劫灶,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年掖桦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了本昏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡枪汪,死狀恐怖涌穆,靈堂內(nèi)的尸體忽然破棺而出怔昨,到底是詐尸還是另有隱情,我是刑警寧澤宿稀,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布趁舀,位于F島的核電站,受9級(jí)特大地震影響祝沸,放射性物質(zhì)發(fā)生泄漏矮烹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一罩锐、第九天 我趴在偏房一處隱蔽的房頂上張望奉狈。 院中可真熱鬧,春花似錦涩惑、人聲如沸仁期。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跛蛋。三九已至,卻和暖如春萍聊,著一層夾襖步出監(jiān)牢的瞬間问芬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工寿桨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留此衅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓亭螟,卻偏偏與公主長(zhǎng)得像挡鞍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子预烙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容