The Go language is used to write instances for communication between the server and the client based on Socket.

Source: Internet
Author: User

The Go language is used to write instances for communication between the server and the client based on Socket.

In golang, the network protocol has been encapsulated very well. To write a Socket Server, we don't need to worry about socket, bind, listen, receive, and other operations like other languages. We just need to use the net package in Golang to conveniently complete the connection and other operations ~
Here, we provide the most basic Socket-based Server statement:
Copy codeThe Code is as follows:
Package main
Import (
"Fmt"
"Net"
"Log"
"OS"
)


Func main (){

// Establish a socket and listen to the port
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)
}
}
// Process the connection
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 core process of the Server to establish and accept a Socket is to remove the pain point of five lines of code in the Go language.
Copy codeThe Code is 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 can Read the content from the Port ~
After the Server is written, the next step is the Client. I will hand you a HelloWorld:
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)

}

We can see that the key of the Client here is
Copy codeThe Code is as follows:
TcpAddr, err: = net. ResolveTCPAddr ("tcp4", server)

Conn, err: = net. DialTCP ("tcp", nil, tcpAddr)

The two steps are mainly responsible for parsing the port and connection ~
After writing the Server and Client, let's run it for a moment :~~
When the connection is successful, the Console prompts that the Server is waiting for connection:

The Server successfully received our Hello-World message. For the line following the red letter, it is the disconnection prompt ~

Here, the most basic Server-Client framework for Socket is coming out ~
If you want the Server to respond to requests from different clients, you only need,
Add a go code before handleConnection (conn net. Conn) to allow the server to concurrently process requests sent by different clients.

Custom communication protocol
After a basic demo is created above, we can initially implement information exchange between the Server and Client ~ In this chapter, I will introduce how to implement a simple communication protocol between the Server and the Client to enhance the stability of the entire information exchange process.
During the interaction between the Server and the client, it is sometimes difficult to avoid network fluctuations. When the communication quality is poor, the Client may not be able to completely send the information stream at one time, the information that is finally sent to the Server may become many segments.
As shown in, it should have been the json transmitted in different entries. The result is connected for some reason. In this case, a problem occurs. How can the Server determine whether the received message is complete ?~

Well, the answer is the topic of this article: when the Server interacts with the Client, add a protocol to encapsulate the interaction between the two, this allows the Server to determine whether the received information is complete. (That is, to solve the subcontracting problem)
Because the main purpose is to allow the Server to determine whether the information sent from the client is complete, the core idea of the entire protocol is not very complicated:
The core of the protocol is to design a header. Each time the Client sends a message, the header is encapsulated, and the Server then parses the message according to the predefined format when receiving the message, in this way, you can easily determine whether the received information is complete based on whether headers is included in the data sent from the Client ~
If the information is complete, the information will be sent to the next logic for processing. If the information is incomplete (the headers is missing), the Server will merge the information with the previous one for further processing.

The following is the protocol code, which consists of two parts: Data encapsulation (Enpack) and resolution (Depack). Enpack is used to encapsulate data transmitted to the server by the Client, the Depack is used by the Server to parse data. The Const part is used to define Headers, And the HeaderLength is the length of Headers, which is used for parsing at the Server end. Here we will talk about ConstMLength, which indicates the length of the information passed in by the Client, because in golang, int is converted to byte, which takes up 4 bytes of space, so it is set to 4. Each time the Client sends a message to the Server, in addition to encapsulating Headers, it also encapsulates the length of the incoming information, which facilitates Server Resolution and verification.
Copy codeThe Code is as follows:
// Communication protocol processing
Package protocol

Import (
"Bytes"
"Encoding/binary"
)
Const (
ConstHeader = "Headers"
ConstHeaderLength = 7
ConstMLength = 4
)

// Encapsulation
Func Enpack (message [] byte) [] byte {
Return 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:]
}

// Convert integer to byte
Func IntToBytes (n int) [] byte {
X: = int32 (n)

BytesBuffer: = bytes. NewBuffer ([] byte {})
Binary. Write (bytesBuffer, binary. BigEndian, x)
Return bytesBuffer. Bytes ()
}

// Convert byte to integer
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 to the Server and Client code. The following is the Server code, which is mainly responsible for parsing the information flow sent by the Client 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 ){


// Buffer to store truncated data
TmpBuffer: = make ([] byte, 0)

// Receive and unpackage
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 there is the Client code. This is much simpler. You just need to encapsulate the information ~ :
Copy codeThe Code is 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)



}

In this way, we can successfully establish a set of custom communication protocols between the Server and the Client. Let's run it to see the effect:

Successfully identifies the information sent from each Client ~~

Articles you may be interested in:
  • Socket instances implemented in the Go Language
  • Go Echo server Method
  • Go Implementation of simple Web Servers
  • Go language server Development and Implementation of the simplest http get and POST Interfaces
  • Go language server development-how a client sends data to the server and receives the returned data
  • Simple TCP client and server implementation for Go language server development
  • Go language implements a simple static WEB Server
  • A simple Web server implemented by the Go Language

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.