Golang implementation of the Chat program server and client code sharing _golang

Source: Internet
Author: User
Tags rand

Implementation logic

1, Golang version 1.3

2. Principle of realization:

1. The main process establishes the TCP listening service and initializes a variable Talkchan: = Make (Map[int]chan string)

2, when the main process accept connection request, use go to start a coprocessor to maintain the connection with the client, the Taokchan into the association Chengri

3, and the client to establish a connection to the coordination of a, send a message to the client, so that it sends its own user information.

4. After receiving the user information sent by the client, the co-process a establishes a corresponding pipeline talkchan[uid] = make (Chan string)

5, the process A and then start a A1 to read the message sent by the client, and to determine who is sent to the message, and then put the message in the corresponding Chan.

6, coprocessor A and then start a A2 to read this user's corresponding pipe, if there is information, then take out to send to the client.

Implementation code

Service-side test code: SERVER.GO

Copy Code code as follows:

Package Main

Import (
"FMT"
"Log"
"NET"
"StrConv"
)

Func handleconnection (Conn net. Conn, Talkchan Map[int]chan string) {
Fmt. Printf ("%p\n", Talkchan)//To check whether the pointer is passed over

/*
Defines the UID of the current user
*/
var curuid int

var err error

/*
Define close Channel
*/
var closed = make (chan bool)

Defer func () {
Fmt. Println ("defer do:conn closed")
Conn. Close ()
Fmt. Printf ("delete userid [%v] from Talkchan", Curuid)
Delete (Talkchan, curuid)
}()

/**
* Prompt the user to set their UID, if not set, then do not face down
*/
for {
Prompt client to set user ID
_, Err = conn. Write ([]byte ("Please set user UID")
If Err!= nil {
Return
}
Data: = Make ([]byte, 1024)
C, ERR: = conn. Read (data)
If Err!= nil {
Closed <-true//this will block | followed by a closed for loop that was not executed to.
Return
}
SUid: = string (Data[0:c])

turn to int type
UID, _: = StrConv. Atoi (SUid)
If UID < 1 {
Continue
}
Curuid = UID
Talkchan[uid] = make (Chan string)
Fmt. PRINTLN (conn, "have set UID", UID, "can Talk")

_, Err = conn. Write ([]byte ("have set UID" +suid+ "can Talk"))
If Err!= nil {
Return
}
Break
}

Fmt. Println ("Err 3")

All current Connections
Fmt. Println (Talkchan)

   /Read data from client
    go func () {
         for {
           //Non-stop reading of data from client
             Data: = Make ([]byte, 1024)
             C, ERR: = conn. Read (data)
            If err!= nil {
                 FMT. Println ("Have no client write", err)
                 closed <-true//Can be used here | Because it is handled with a new thread on the go. |  even if Chan is blocked, the back will execute to read closed this Chan
            }

Clientstring: = string (Data[0:c])

The data from the client is written to the corresponding Chan.
If Curuid = 3 {
TALKCHAN[4] <-clientstring
} else {
TALKCHAN[3] <-clientstring
}

}
}()

   /*
        Read the data from Chan to the client and write it to the client
     */
    go func () {
        for {
             talkstring: = <-talkchan[curuid]
             _, Err = conn. Write ([]byte (talkstring))
            If err!= nil {
                closed <-true
           }
        }
   } ()

/*
Check to see if the connection has been closed if closed then eject the thread to execute the defer statement
*/
for {
If <-closed {
Return
}
}
}

Func Main () {

/**
Establish a listening link
*/
ln, ERR: = Net. Listen ("TCP", "127.0.0.1:6010")
If Err!= nil {
Panic (ERR)
}

Create a pipe

Talkchan: = Map[f]
Talkchan: = Make (Map[int]chan string)

Fmt. Printf ("%p\n", Talkchan)

/*
Listen for a connection request from the client.
*/
for {
Fmt. PRINTLN ("Wait Connect ...")
Conn, err: = ln. Accept ()
If Err!= nil {
Log. Fatal ("Get Client Connection Error:", err)
}

Go handleconnection (conn, Talkchan)
}
}

Client Test code: CLIENT.GO

Copy Code code as follows:

Package Main

Import (
"FMT"
"Math/rand"
"NET"
)

Func Main () {
Conn, Err: = Net. Dial ("TCP", "127.0.0.1:6010")
If Err!= nil {
Panic (ERR)
}

Fmt. fprintf (conn, "Hello server\n")

Defer Conn. Close ()
Go Writefromserver (conn)

for {
var talkcontent string
Fmt. SCANLN (&talkcontent)

If Len (talkcontent) > 0 {
_, Err = conn. Write ([]byte (Talkcontent))
If Err!= nil {
Fmt. Println ("Write to server Error")
Return
}
}
}
}

Func Connect () {
Conn, Err: = Net. Dial ("TCP", "127.0.0.1:6010")
If Err!= nil {
Panic (ERR)
}

Fmt. fprintf (conn, "Hello server\n")

Defer Conn. Close ()
Go Writefromserver (conn)

for {
var talkcontent string
Fmt. SCANLN (&talkcontent)

If Len (talkcontent) > 0 {
_, Err = conn. Write ([]byte (Talkcontent))
If Err!= nil {
Fmt. Println ("Write to server Error")
Return
}
}
}
}

Func writefromserver (Conn net. Conn) {
Defer Conn. Close ()
for {
Data: = Make ([]byte, 1024)
C, ERR: = conn. Read (data)
If Err!= nil {
Fmt. PRINTLN ("Rand", Rand.) Intn (a), "have no server write", err)
Return
}
Fmt. Println (String (data[0:c]) + "\ n")
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.