The go language is based on the socket to write the server-side communication with the client instance

Source: Internet
Author: User
In Golang, the network protocol has been encapsulated very well, want to write a socket server, we do not need to like other languages for socket, bind, listen, receive and so on a series of operations headache, As long as the use of Golang in the net package can be very convenient to complete the operation of the connection ~
Here, the most basic socket-based server notation is given:
Copy CodeThe code is as follows:


Package Main
Import (
"FMT"
"NET"
"Log"
"OS"
)


Func Main () {

Setting up sockets, listening ports
Netlisten, err: = Net. Listen ("TCP", "localhost:1024")
CheckError (ERR)
Defer Netlisten.close ()

Log ("Waiting for Clients")
for {
Conn, err: = Netlisten.accept ()
If err! = Nil {
Continue
}

LOG (Conn. Remoteaddr (). String (), "TCP Connect Success")
Handleconnection (conn)
}
}
Processing connections
Func handleconnection (Conn net. Conn) {

Buffer: = Make ([]byte, 2048)

for {

N, err: = conn. Read (buffer)

If err! = Nil {
LOG (Conn. Remoteaddr (). String (), "Connection error:", err)
Return
}


LOG (Conn. Remoteaddr (). String (), "Receive Data string:\n", String (Buffer[:n]))

}

}
Func Log (v. ... interface{}) {
Log. Println (v ...)
}

Func checkerror (err error) {
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}
}

Well, the 10 lines of code in the Go language have 5 lines of error, and you can see that the server wants to build and accept a socket, and the core process is
Copy the Code code as follows:


Netlisten, err: = Net. Listen ("TCP", "localhost:1024")

Conn, err: = Netlisten.accept ()

N, err: = conn. Read (buffer)


In these three steps, through listen, Accept and read, we successfully bound a port and was able to read the content from that port ~
After the server is written, next is the client side, I handwritten a helloworld to everyone:
Copy CodeThe code is as follows:


Package Main

Import (
"FMT"
"NET"
"OS"
)

Func Sender (Conn net. Conn) {
Words: = "Hello world!"
Conn. Write ([]byte (words))
Fmt. PRINTLN ("Send Over")

}



Func Main () {
Server: = "127.0.0.1:1024"
TCPADDR, err: = Net. RESOLVETCPADDR ("TCP4", server)
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}

Conn, Err: = Net. DIALTCP ("TCP", Nil, tcpaddr)
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}


Fmt. PRINTLN ("Connect Success")
Sender (conn)

}


As you can see, the key to the client here is
Copy CodeThe code is as follows:


TCPADDR, err: = Net. RESOLVETCPADDR ("TCP4", server)

Conn, Err: = Net. DIALTCP ("TCP", Nil, tcpaddr)


These two steps are primarily responsible for parsing ports and connections ~
After writing the server and client, let's run a look: ~ ~
Running successfully, console appears with the server waiting for the connection prompt:

Server side successfully received our Hello-world, as for the following line of red words, is the hint of disconnection ~

Here, one of the most basic server-client frames to use the socket is out ~
If you want the server to be able to respond to requests from different clients, we just need to do so in the main portal of the server-side code.
In Handleconnection (conn net. Conn) This code is preceded by a go that allows the server to concurrently process requests from different client

Custom Communication Protocols
After we have made a most basic demo, we can initially realize the exchange of information between the server and the client ~ This chapter I will explain how to implement a simple communication protocol between server and client, thus enhancing the stability of the whole information communication process.
In the interaction between server and client, it is sometimes difficult to avoid the network fluctuations, and when the quality of communication is poor, the client may not be able to send the flow of information to complete one time, eventually uploading to the server is likely to become many segments.
As shown, it should be a sub-stripe of the JSON, the result for some reason connected together, this time there will be problems, the server side how to determine whether the message received is complete? ~

Well, the answer is the subject of this article: when the server interacts with the client, add a communication protocol (protocol) that allows the interaction of the two to be encapsulated by this protocol, allowing the server to determine whether the received information is a complete paragraph. (i.e. to solve the problem of subcontracting)
Because the main purpose is to allow the server to determine whether the information sent by the client is complete, the core idea of the entire protocol is not very complex:
The core of the protocol is to design a head (headers) that encapsulates the header each time the client sends a message, and then allows the server to parse the message in a predetermined format each time the message is received, so that the data from the client contains headers , it is easy to judge whether the information received is complete ~
If the information is complete, the message is sent to the next logic for processing, and if the information is incomplete (missing headers), then the server will merge this information with the previous information to continue processing.

The following is the protocol part of the code, mainly divided into data encapsulation (Enpack) and parsing (depack) two parts, where Enpack for the client side will be passed to the server data encapsulation, and Depack is used by the server to parse the data, Where the const section is used to define headers,headerlength is the length of the headers for subsequent server-side parsing. Here's the Constmlength, which represents the length of the incoming message for the client, because in Golang, the int goes to byte and takes up 4 of the length of space, so it is set to 4. Each time the client sends a message to the server, the length of the incoming information is also encapsulated in addition to the headers encapsulation, which makes it easier for the server to parse and verify.
Copy the Code code as follows:


Communication protocol Processing
Package protocol

Import (
"Bytes"
"Encoding/binary"
)
Const (
Constheader = "Headers"
Constheaderlength = 7
Constmlength = 4
)

Sealing Package
Func enpack (message []byte) []byte {
Return Append (Append ([]byte (Constheader), inttobytes (len (message)), message ...)
}

Unpack
Func depack (buffer []byte, Readerchannel Chan []byte] []byte {
Length: = Len (buffer)

var i int
For i = 0; i < length; i = i + 1 {
If length < I+constheaderlength+constmlength {
Break
}
If string (buffer[i:i+constheaderlength]) = = Constheader {
Messagelength: = Bytestoint (Buffer[i+constheaderlength:i+constheaderlength+constmlength])
If length < I+constheaderlength+constlength+messagelength {
Break
}
Data: = Buffer[i+constheaderlength+constmlength:i+constheaderlength+constmlength+messagelength]
Readerchannel <-Data

}
}

if i = = length {
return make ([]byte, 0)
}
Return Buffer[i:]
}

Shaping into bytes
Func inttobytes (n int) []byte {
X: = Int32 (N)

Bytesbuffer: = bytes. Newbuffer ([]byte{})
Binary. Write (Bytesbuffer, Binary. Bigendian, X)
Return Bytesbuffer.bytes ()
}

Converting bytes into shaping
Func Bytestoint (b []byte) int {
Bytesbuffer: = bytes. Newbuffer (b)

var x int32
Binary. Read (Bytesbuffer, Binary. Bigendian, &x)

return int (x)
}


After the protocol is written, the next step is to apply the protocol in the server and client code, which is the server-side code that is primarily responsible for parsing the information flow that the client sends through the protocol:
Copy CodeThe code is as follows:


Package Main

Import (
"Protocol"
"FMT"
"NET"
"OS"
)

Func Main () {
Netlisten, err: = Net. Listen ("TCP", "localhost:6060")
CheckError (ERR)

Defer Netlisten.close ()

Log ("Waiting for Clients")
for {
Conn, err: = Netlisten.accept ()
If err! = Nil {
Continue
}

Timeousec: =10
Conn.
LOG (Conn. Remoteaddr (). String (), "TCP Connect Success")
Go handleconnection (conn)

}
}

Func handleconnection (Conn net. Conn) {


buffers, storing truncated data
Tmpbuffer: = Make ([]byte, 0)

Receive unpacking
Readerchannel: = Make (chan []byte, 16)
Go Reader (Readerchannel)

Buffer: = Make ([]byte, 1024)
for {
N, err: = conn. Read (buffer)
If err! = Nil {
LOG (Conn. Remoteaddr (). String (), "Connection error:", err)
Return
}

Tmpbuffer = protocol. Depack (Append (Tmpbuffer, buffer[:n] ...), Readerchannel)
}
Defer Conn. Close ()
}

Func Reader (Readerchannel Chan []byte) {
for {
Select {
Case data: = <-readerchannel:
Log (String data)
}
}
}

Func Log (v. ... interface{}) {
Fmt. Println (v ...)
}

Func checkerror (err error) {
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}
}

Then the client side of the code, this is much simpler, as long as the information to encapsulate it can be ~:
Copy the Code code as follows:


Package Main
Import (
"Protocol"
"FMT"
"NET"
"OS"
"Time"
"StrConv"

)

Func Send (conn net. Conn) {
For I: = 0; I < 100; i++ {
Session:=getsession ()
Words: = "{\" id\ ":" + StrConv. Itoa (i) + "\", \ "session\": "+session +" 2015073109532345\ ", \" meta\ ": \" golang\ ", \" content\ ": \" message\ "}"
Conn. Write (protocol. Enpacket ([]byte (words)))
}
Fmt. PRINTLN ("Send Over")
Defer Conn. Close ()
}

Func getsession () string{
Gs1:=time. Now (). Unix ()
Gs2:=strconv. Formatint (gs1,10)
Return GS2
}

Func Main () {
Server: = "localhost:6060"
TCPADDR, err: = Net. RESOLVETCPADDR ("TCP4", server)
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}

Conn, Err: = Net. DIALTCP ("TCP", Nil, tcpaddr)
If err! = Nil {
Fmt. fprintf (OS. Stderr, "Fatal Error:%s", err. Error ())
Os. Exit (1)
}


Fmt. PRINTLN ("Connect Success")
Send (conn)



}


So that we can successfully implement a set of custom basic communication protocols between server and client let's run a look at the effect:

Successful identification of each client sent the message ~ ~

  • Related Article

    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.