socket:tcp/udp、ip构成了网络通信的基石,tcp/ip是面向连接的通信协议

要求建立连接时进行3次握手确保连接已被建立,关闭连接时需要4次通信来保证客户端和,服务端都已经关闭

在通信过程中还有保证数据不丢失,在连接不畅通时还需要进行超时重试等等

所以socket就是封装了这一套基于tcp/udp/ip协议细节,提供了一系列套接字接口进行通信

client端通过以下方式与Server端进行通信

先看看再golang中如何进行socket编程

  1. // 创建socket文件描述符,绑定ip:port,改变socket状态为监听状态
  2. ln, err := net.Listen("tcp", addr)
  3. // 返回时关闭tcp连接
  4. defer l.Close()
  5. if err != nil {
  6. return err
  7. }
  8. for {
  9. // 从socket recive队列里获取一个建立好的连接
  10. conn,err := ln.Accept()
  11. if err != nil {
  12. return err
  13. }
  14. // 新起一个goroutine处理连接
  15. go handler(conn)
  16. }
  17.  
  18. func handler(conn net.Con) {
  19. // 关闭连接
  20. conn.Close()
  21. }

介绍几个跟socket相关的底层函数

socketFunc func(int, int, int) (int, error) = syscall.Socket //创建一个socket文件描述符
func Bind(fd int, sa Sockaddr) (err error) //绑定一个本机IP:port到socket文件描述符上
listenFunc func(int, int) error = syscall.Listen //监听是否有tcp连接请求
acceptFunc func(int) (int, syscall.Sockaddr, error) = syscall.Accept //获取一个建立好的tcp连接
connectFunc func(int, syscall.Sockaddr) error = syscall.Connect //发起tcp连接请求
closeFunc func(int) error = syscall.Close //关闭连接

下面介绍下在golang中socket接口是如何通过这几个底层函数完成socket封装的。

socket:创建的socket默认是阻塞的,通过syscall.SetNonblock()可以将socket设置为非阻塞模式

  1. func sysSocket(family, sotype, proto int) (int, error) {

  2. syscall.ForkLock.RLock()
    //创建socket文件描述符
  3. s, err := socketFunc(family, sotype, proto)
  4. if err == nil {
         // 关闭从父线程拷贝过来的文件描述符后,再执行子线程程序
  5. syscall.CloseOnExec(s)
  6. }
  7. syscall.ForkLock.RUnlock()
  8. if err != nil {
  9. return -, os.NewSyscallError("socket", err)
  10. }
  11.  
  12. //设置socket位非阻塞
  13. if err = syscall.SetNonblock(s, true); err != nil {
  14. closeFunc(s)
  15. return -, os.NewSyscallError("setnonblock", err)
  16. }
  17. return s, nil
  18. } 

listen:设置socket文件描述符为监听状态,把监听到的请求放入未完成的请求队列中,完成3次握手后,会把连接放入已完成的请求队列中等待accept获取处理

  1. func (fd *netFD) listenStream(laddr sockaddr, backlog int) error {
  2. if err := setDefaultListenerSockopts(fd.sysfd); err != nil {
  3. return err
  4. }
  5. if lsa, err := laddr.sockaddr(fd.family); err != nil {
  6. return err
  7. } else if lsa != nil {
  8.    //绑定ip:port
  9. if err := syscall.Bind(fd.sysfd, lsa); err != nil {
  10. return os.NewSyscallError("bind", err)
  11. }
  12. }
  13. //监听socket文件描述符
  14. if err := listenFunc(fd.sysfd, backlog); err != nil {
  15. return os.NewSyscallError("listen", err)
  16. }
  17. if err := fd.init(); err != nil {
  18. return err
  19. }
  20. lsa, _ := syscall.Getsockname(fd.sysfd)
  21. fd.setAddr(fd.addrFunc()(lsa), nil)
  22. return nil
  23. }

accept:从已完成的队列里取出一个tcp连接,返回的是由内核根据当前socket信息创建的全新的tcp连接来处理数据的,同时原始创建好的socket还可以继续监听其他连接请求,如果没有获取到则阻塞当前goroutine

  1. func accept(s int) (int, syscall.Sockaddr, error) {
    //获取连接
  2. ns, sa, err := acceptFunc(s)
  3. if err == nil {
  4. syscall.CloseOnExec(ns)
  5. }
  6. if err != nil {
  7. return -1, nil, os.NewSyscallError("accept", err)
  8. }
    //设置为非阻塞
  9. if err = syscall.SetNonblock(ns, true); err != nil {
  10. closeFunc(ns)
  11. return -1, nil, os.NewSyscallError("setnonblock", err)
  12. }
  13. return ns, sa, nil
  14. }

connect:client端发起连接请求

  1. //发起连接请求
    func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time, cancel <-chan struct{}) error {
    switch err := connectFunc(fd.sysfd, ra); err {
      //异常处理
        ....
    }
    }

close:

  1. //关闭连接请求
    func (fd *netFD) destroy() {
    //关闭连接
  2. fd.pd.Close()
    //释放系统资源
  3. closeFunc(fd.sysfd)
  4. fd.sysfd = -
  5. runtime.SetFinalizer(fd, nil)
  6. }

golang socket 分析的更多相关文章

  1. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  2. golang socket与Linux socket比较分析

    在posix标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带runtime的跨平台编程语言,Go中提供给开发者的socket API是建立在操作系统原生socket ...

  3. Linux下Golang Socket编程原理分析与代码实现

    在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...

  4. golang socket 实现分析(一)

    socket:tcp/udp.ip构成了网络通信的基石,tcp/ip是面向连接的通信协议 要求建立连接时进行3次握手确保连接已被建立,关闭连接时需要4次通信来保证客户端和,服务端都已经关闭 在通信过程 ...

  5. Golang socket

    1.本例子实现了一个简单的TCP echo.客户端发送Hello,服务端回应World. 参考:<Socket编程> 2.服务端代码 package main import ( " ...

  6. golang trace 分析 简例

    今天,通过一个例子,一方面熟悉trace在自定义范围内的分析,另一方面golang 在协程调度策略上的浅析. Show Code // trace_example.go package main im ...

  7. golang逃逸分析和竞争检测

    最近在线上发现一块代码逻辑在执行N次耗时波动很大1ms~800ms,最开始以为是gc的问题,对代码进行逃逸分析,看哪些变量被分配到堆上了,后来发现是并发编程时对一个切片并发的写,导致存在竞争,类似下面 ...

  8. [转] golang socket

    server.go package main import ( "net" "fmt" "io/ioutil" "time&quo ...

  9. Golang Socket编程

    Socket编程 在很多底层网络应用开发者的眼里一切编程都是Socket,话虽然有点夸张,但却也几乎如此了,现在的网络编程几乎都是用Socket来编程.你想过这些情景么?我们每天打开浏览器浏览网页时, ...

随机推荐

  1. 数据挖掘学习笔记--AdaBoost算法(一)

    声明: 这篇笔记是自己对AdaBoost原理的一些理解,如果有错,还望指正,俯谢- 背景: AdaBoost算法,这个算法思路简单,但是论文真是各种晦涩啊-,以下是自己看了A Short Introd ...

  2. ArcGIS10.2直连PostgreSQL存在问题

    现象: 将下载到的libeay32.dll, libiconv-2.dll, libintl-8.dll, libpq.dll, ssleay32.dll文件拷贝到Desktop 安装目录的bin目录 ...

  3. Hadoop权威指南:通过distcp并行复制

    Hadoop权威指南:通过distcp并行复制 distcp是一个分布式复制程序,改程序可以从Hadoop文件系统间复制大量数据,也可以将大量的数据复制到Hadoop中 distcp的典型应用是在两个 ...

  4. [html5] 学习笔记-SVG

    1.SVG介绍:什么是SVG? 1)SVG指可伸缩矢量图形(Scalable Vector Graphics) 2)SVG用来定义用于网络的基于矢量的图形 3)SVG使用XML格式定义图形 4)SVG ...

  5. (原创)Java多线程作业题报java.lang.IllegalMonitorStateException解决

    作业: 有一个水池,水池容量500L,一边为进水口,一边为出水口,要求进水放水不能同时进行,水池一旦满了不能继续注水,一旦空了,不能继续放水,进水速度5L/s,放水速度2L/s. 这是我学多线程时做的 ...

  6. Git中.gitignore文件的使用

      在我们使用git的时候,有时候就不想传一些与代码无关的文件到远程仓库中,比如说编译后的文件,.gitignore就可以帮助我们处理这些文件. 生成.gitignore文件 在git bash中使用 ...

  7. executssql 函数的每一句代码的意思

    Public Function Executesql(ByVal sql As String, Msgstring As String) As ADODB.Recordset Dim cnn As A ...

  8. 做一个项目前搭建一个tabBar(一)框架

    前言 通常做一个项目前,不算开始讨论需求,分析产品等等,一开始会给我们搭建一个框架,今天简单说一下搭建框架. github网址:https://github.com/Moonths/iWatch.gi ...

  9. HNOI2015 Day 2题解

    昨天做了HNOI day 2,感觉好像还是可做的,想当年什么splay还是高级算法,现在点剖什么就老考了简直丧病,虽然第二题还没写那就先当下嘴巴选手吧= = T1:[HNOI2015]落忆枫音 描述: ...

  10. Ajax跨域实现淘宝/百度搜索下拉提示效果

    最近学到Ajax,觉得自己对与前后端的数据交互有了一个基本的了解.下面是Ajax应用到淘宝/百度的搜索功能的一个简单的小实例,就是输入一个词,下拉框中自动显示匹配的内容: