Golang网络编程

互联网协议介绍引入

1. 物理层(Physical Layer):
   - 功能:物理层负责定义物理介质传输数据的方式和规范,它传输的是原始数据比特流。
   - 协议:Ethernet、Wi-Fi、USB、光纤等。
   - 例子:将数据通过网线传输的过程类似于我们通过电话线进行声音通信。

2. 数据链路层(Data Link Layer):
   - 功能:数据链路层负责将数据分成帧,并进行传输错误的检测和纠正。
   - 协议:Ethernet(MAC地址)、PPP(点对点协议)等。
   - 例子:当我们接收到一封电子邮件时,电子邮件被分成小块,每个块都有一个标识符,以确保它们的正确接收。

3. 网络层(Network Layer):
   - 功能:网络层负责在网络中选择最佳的路径进行数据传输和路由。
   - 协议:IP(Internet协议)、ICMP(Internet控制消息协议)等。
   - 例子:当我们使用导航应用程序时,它会根据我们的位置、交通情况和其他因素决定最佳路线。

4. 传输层(Transport Layer):
   - 功能:传输层负责提供可靠的端到端数据传输和错误恢复。
   - 协议:TCP(传输控制协议)、UDP(用户数据报协议)等。
   - 例子:当我们下载文件时,传输层确保文件被正确地分割成数据包,并且在接收端按正确顺序重新组装。

5. 会话层(Session Layer):
   - 功能:会话层负责建立、管理和终止网络中的会话。
   - 协议:TLS(安全传输层协议)、SSH(安全外壳协议)等。
   - 例子:当我们在网上购物时,会话层确保我们与商家之间的通信是加密和安全的。

6. 表示层(Presentation Layer):
   - 功能:表示层负责数据的格式化、加密和压缩,确保不同系统间的数据能正确解释和理解。
   - 协议:JPEG(图像压缩标准)、MPEG(音视频压缩标准)等。
   - 例子:当我们分享相片时,表示层负责将图像转换成适合传输和显示的格式。

7. 应用层(Application Layer):
   - 功能:应用层负责发送和接收应用程序之间的数据,并提供应用程序所需的服务。
   - 协议:HTTP(超文本传输协议)、FTP(文件传输协议)、SMTP(简单邮件传输协议)等。
   - 例子:当我们使用浏览器访问网页时,应用层使用HTTP协议来请求和接收网页内容。

如下图所示,发送方的HTTP数据经过互联网的传输过程中会依次添加各层协议的标头信息,接收方收到数据包之后再依次根据协议解包得到数据。

socket图解

 什么是套接字

Socket(套接字)是一种用于实现网络通信的编程接口;

允许不同的计算机通过网络互相传递数据;

Socket提供了一种标准的编程接口,使得开发者可以使用通用的网络协议(如TCP/IP)进行网络通信。

下面举生活中的例子:

Socket是应用层与传输层之间的接口,它基于计算机网络原理,将网络传输分为两个角色:服务器(Server)和客户端(Client)

CS架构

- 服务器端(Server):服务器端监听特定的网络端口,等待客户端的连接请求。一旦接收到连接请求,服务器端创建一个新的Socket与客户端进行通信。

- 客户端(Client):客户端发起连接请求,并通过Socket与服务器端建立通信。客户端可以发送请求数据到服务器,并接收服务器的响应数据。

Socket操作涉及以下几个主要步骤:

1. 创建Socket:服务器端和客户端都需要创建一个Socket对象,用来进行通信(该对象包含了IP地址和端口号等信息)

2. 绑定Socket:服务器端需要将Socket绑定到一个具体的IP地址和端口号上,以便客户端能够连接。

3. 监听连接:服务器端通过Socket监听特定的端口,等待客户端的连接请求。

4. 接受连接:一旦服务器端接收到连接请求,它会创建一个新的Socket对象与客户端进行通信。

5. 数据传输:通过Socket对象,服务器端和客户端可以相互发送数据。

6. 关闭连接:通信完成后,服务器和客户端都可以关闭Socket连接。

生活中的例子可以是使用手机应用程序与服务器进行通信。举个例子,考虑一个聊天应用程序,其包括一个服务器和多个客户端。服务器负责接收和分发消息,而客户端负责发送和接收用户的消息。

在这个场景中,服务器端的应用程序创建了一个Socket并在指定端口上侦听。多个客户端应用程序也创建了各自的Socket对象,并使用服务器的IP地址和端口号连接到服务器。

一旦连接建立,客户端通过其Socket向服务器发送消息。服务器接收到消息后,可以将其转发给其他客户端。这样,通过Socket的使用,服务器和客户端可以实现实时的聊天功能。

总结来说,Socket是一种网络编程接口,用于在服务器端和客户端之间建立通信。通过Socket,计算机可以通过网络传输数据,实现各种应用程序的网络通信。

常用的Socket类型有两种:流式Socket和数据报式Socket,流式是一种面向连接的Socket,针对于面向连接的TCP服务应用,数据报式Socket是一种无连接的Socket,针对于无连接的UDP服务应用

TCP:比较靠谱,面向连接,比较慢

UDP:不是太靠谱,比较快

前提概念几则

net包

Go语言实现TCP通信

TCP协议

TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网际协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。

TCP服务端

一个TCP服务端可以同时连接很多个客户端,例如世界各地的用户使用自己电脑上的浏览器访问淘宝网。因为Go语言中创建多个goroutine实现并发非常方便和高效,所以我们可以每建立一次链接就创建一个goroutine去处理。

TCP服务端程序的处理流程:

    1.监听端口
    2.接收客户端请求建立链接
    3.创建goroutine处理链接。   

TCP服务端代码如下:

package main

import (
	"bufio"
	"fmt"
	"net"
)



// 服务端
func process(conn net.Conn) {
    defer conn.Close() // 关闭连接
    for {
        reader := bufio.NewReader(conn)
        var huancun [128]byte
        n, err := reader.Read(huancun[:]) // 读取数据
        if err != nil {
            fmt.Println("从客户端读取数据失败,报错为:", err)
            break
        }
        data := string(huancun[:n])
        fmt.Println("收到client端发来的数据:", data)
        conn.Write([]byte(data)) // 发送数据
    }
}

func main() {
    listen, err := net.Listen("tcp", "127.0.0.1:30000")
    if err != nil {
        fmt.Println("listen failed, err:", err)
        return
    }
    for {
        conn, err := listen.Accept() // 建立连接
        if err != nil {
            fmt.Println("accept failed, err:", err)
            continue
        }
        go process(conn) // 启动一个goroutine处理连接
    }
}   
这是一个简单的TCP服务器程序,它监听在本地的30000端口上,并接受客户端的连接。
一旦有连接建立,就会启动一个goroutine来处理连接。

在处理连接的goroutine中,首先创建一个bufio.Reader对象来读取客户端发送的数据。
然后创建一个长度为128的字节数组作为缓冲区,
使用reader.Read()方法从客户端读取数据,并将读取到的数据存储在缓冲区中。

如果读取过程中发生错误,就打印错误信息并退出循环。
否则,将读取到的数据转换为字符串,并打印出来。然后将读取到的数据通过conn.Write()方法发送回客户端。

在main函数中,首先使用net.Listen()方法创建一个监听器,监听在本地的30000端口上。
如果监听失败,就打印错误信息并返回。否则,进入一个无限循环,不断接受客户端的连接。

在每次接受连接时,如果出现错误,则打印错误信息并继续下一次循环。
否则,启动一个goroutine来处理该连接,即调用process()函数。这样可以同时处理多个客户端的连接。

编译为可执行文件

go build -o server.exe
TCP客户端模拟
package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)



// 客户端
func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:30000")
    if err != nil {
        fmt.Println("err :", err)
        return
    }
    defer conn.Close() // 关闭连接
    inputReader := bufio.NewReader(os.Stdin)
    for {
        input, _ := inputReader.ReadString('\n') // 读取用户输入
        inputInfo := strings.Trim(input, "\r\n")
        if strings.ToUpper(inputInfo) == "Q" { // 如果输入q就退出
            return
        }
        _, err = conn.Write([]byte(inputInfo)) // 发送数据
        if err != nil {
            return
        }
        buf := [512]byte{}
        n, err := conn.Read(buf[:])
        if err != nil {
            fmt.Println("recv failed, err:", err)
            return
        }
        fmt.Println(string(buf[:n]))
    }
}   
这是一个基于TCP的简单客户端代码。它通过网络连接到指定的地址和端口
并且可以发送用户输入的数据并接收服务器返回的数据。

在主函数中,首先通过`net.Dial()`函数建立与服务器的连接,并检查是否有错误发生。

如果有错误,将打印错误信息并返回。

然后,通过`bufio.NewReader()`创建一个读取用户输入的读取器。

然后使用一个无限循环来不断读取用户输入。

在每次循环中,使用`inputReader.ReadString('\n')`读取用户输入。然后使用`strings.Trim(input, "\r\n")`去掉换行符、回车符。

下一步是检查用户输入是否为大写的"Q",如果是的话,退出循环,在此之前关闭连接。
如果不是"Q",则使用`conn.Write()`将用户输入的数据发送到服务器。

然后,使用`conn.Read()`从服务器接收数据,存储在缓冲区`buf`中。读取到的字节数存储在变量`n`中,如果有错误发生,则打印错误信息并返回。

最后,使用`fmt.Println(string(buf[:n]))`打印从服务器接收到的数据。循环会继续,等待用户的下一次输入。

编译为可执行文件

go build -o client.exe

测试一下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵唯一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值