• [Golang] 从零开始写Socket Server(1): Socket-Client框架


    第一次跑到互联网公司实习 。。感觉自己进步飞快啊~第一周刚写了个HTTP服务器用于微信公共号的点餐系统~ 第二周就直接开始一边自学Go语言一边写用于Socket的服务器了。。。

    因为发现Golang这一块资料挺少的,接下来我会在Blog里把整个Server的Coding,还有遇到的坑都记录下来~

    在golang中,网络协议已经被封装的非常完好了,想要写一个Socket的Server,我们并不用像其他语言那样需要为socket、bind、listen、receive等一系列操作头疼,只要使用Golang中自带的net包即可很方便的完成连接等操作~

    在这里,给出一个最最基础的基于Socket的Server的写法:

    [plain] view plain copy
     
    1. package main  
    2. import (  
    3.     "fmt"  
    4.     "net"  
    5.     "log"  
    6.     "os"  
    7. )  
    8.   
    9.   
    10. func main() {  
    11.   
    12. //建立socket,监听端口  
    13.     netListen, err := net.Listen("tcp", "localhost:1024")  
    14.     CheckError(err)  
    15.     defer netListen.Close()  
    16.   
    17.     Log("Waiting for clients")  
    18.     for {  
    19.         conn, err := netListen.Accept()  
    20.         if err != nil {  
    21.             continue  
    22.         }  
    23.   
    24.         Log(conn.RemoteAddr().String(), " tcp connect success")  
    25.         handleConnection(conn)  
    26.     }  
    27. }  
    28. //处理连接  
    29. func handleConnection(conn net.Conn) {  
    30.   
    31.     buffer := make([]byte, 2048)  
    32.   
    33.     for {  
    34.   
    35.         n, err := conn.Read(buffer)  
    36.   
    37.         if err != nil {  
    38.             Log(conn.RemoteAddr().String(), " connection error: ", err)  
    39.             return  
    40.         }  
    41.   
    42.   
    43.         Log(conn.RemoteAddr().String(), "receive data string: ", string(buffer[:n]))  
    44.   
    45.     }  
    46.   
    47. }  
    48. func Log(v ...interface{}) {  
    49.     log.Println(v...)  
    50. }  
    51.   
    52. func CheckError(err error) {  
    53.     if err != nil {  
    54.         fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
    55.         os.Exit(1)  
    56.     }  
    57. }  


    唔,抛除go语言里面10行代码有5行error的蛋疼之处,你可以看到,Server想要建立并接受一个Socket,其核心流程就是

    [plain] view plain copy
     
    1. netListen, err := net.Listen("tcp", "localhost:1024")  
    [plain] view plain copy
     
    1. conn, err := netListen.Accept()  
    [plain] view plain copy
     
    1. n, err := conn.Read(buffer)  

    这三步,通过Listen、Accept 和Read,我们就成功的绑定了一个端口,并能够读取从该端口传来的内容~

    Server写好之后,接下来就是Client方面啦,我手写一个HelloWorld给大家:

    [plain] view plain copy
     
    1. package main  
    2.   
    3. import (  
    4.     "fmt"  
    5.     "net"  
    6.     "os"  
    7. )  
    8.   
    9. func sender(conn net.Conn) {  
    10.         words := "hello world!"  
    11.         conn.Write([]byte(words))  
    12.     fmt.Println("send over")  
    13.   
    14. }  
    15.   
    16.   
    17.   
    18. func main() {  
    19.     server := "127.0.0.1:1024"  
    20.     tcpAddr, err := net.ResolveTCPAddr("tcp4", server)  
    21.     if err != nil {  
    22.         fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
    23.         os.Exit(1)  
    24.     }  
    25.   
    26.     conn, err := net.DialTCP("tcp", nil, tcpAddr)  
    27.     if err != nil {  
    28.         fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())  
    29.         os.Exit(1)  
    30.     }  
    31.   
    32.   
    33.     fmt.Println("connect success")  
    34.     sender(conn)  
    35.   
    36. }  

    可以看到,Client这里的关键在于
    [plain] view plain copy
     
    1. tcpAddr, err := net.ResolveTCPAddr("tcp4", server)  

    [plain] view plain copy
     
    1. conn, err := net.DialTCP("tcp", nil, tcpAddr)  

    这两步,主要是负责解析端口和连接~

    写好Server和Client之后,让我们运行一下看看:~~

    成功运行,Console出现Server等待连接的提示:

    然后我们运行Client:

    成功连接Server啦,让我们看看Server那边的成果:

    Server端成功的收到了我们的Hello-World啦,至于后面的那行红字,则是断开连接的提示~

    到这里,一个最基础的使用Socket的Server-Client框架就出来啦~

    如果想要让Server能够响应来自不同Client的请求,我们只要在Server端的代码的main入口中,

    在 handleConnection(conn net.Conn) 这句代码的前面加上一个 go,就可以让服务器并发处理不同的Client发来的请求啦

    关于Golang的并发处理,可以参考这里 Golang并行计算

    下一篇,我会写一下如何在Server和Client中设计一个通讯协议,从而达到自己的一些特殊要求~

  • 相关阅读:
    VMwarePro密钥
    Windows事件ID
    python中安装下载超时,下载不了安装包
    PNG文件结构分析 ---Png解析
    世界协调时间(UTC)与中国标准时间
    计算机用户权限比较
    pikachu-xx型注入
    pikachu-搜索型注入 #手工注入
    显示桌面图标
    SQL2005 数据库还原到 SQL2008 错误 3145 解决办法
  • 原文地址:https://www.cnblogs.com/cnsanshao/p/7085862.html
Copyright © 2020-2023  润新知