Go语言进阶,interface接口,socket套接字

        虽然Go语言没有类的概念,也没有所谓继承,所以谈不上属于真正的面向对象的编程语言,但是拥有非常灵活的接口概念,而且独特之处在于它是满足隐式实现的,不需要类似implements这样的关键字,编译器自动在需要的时候检查两个类型之间的实现关系。

接口是一种双方的约定,其接口类型是对其他类型行为的抽象和概括,接口的实现者不需要关心接口会被怎样使用,调用者也不需要关心接口的实现细节,接口的定义和结构体类似,所以也是一种自定义类型,是一种抽象结构,不会暴露所含数据的格式、类型和结构。

接口的实现与错误处理

接口声明格式如下: 

type 名称 interface{
    方法名称1(参数...) (返回值...)
    方法名称2(参数...) (返回值...)
    ...
}

具体来看一个示例,熟悉接口的声明与调用,然后针对接口的规范,我们故意设计一些出错的情况来了解它:

package main

import (
	"fmt"
)

// 声明一个Tester接口
type Tester interface {
	PrintData(info interface{}) error
}

// 定义一个结构体实现这个接口
type person struct {
}

// 实现接口里面的方法
// error返回类型,表示可能发生的错误
func (p *person) PrintData(info interface{}) error {
	fmt.Println(info)
	return nil
}

func main() {
	// 实例化person,类型是*person
	p := new(person)
	// 声明一个接口变量
	var tester Tester
	//将*person类型的p赋值给接口变量,虽然两个变量类型不一致。但是tester是一个接口,且p已经完全实现了接口的所有方法,因此赋值是成功的
	tester = p
	// 接口变量实现其定义的方法
	tester.PrintData("你好,寅恪光潜")
}

//你好,寅恪光潜

错误一,方法名称需一致

如果我们将PrintData方法名称修改为PrintData1,也就是说不去实现接口中的PrintData方法,虽然PrintData1写法都是合乎规范的,但由于修改的名称方法,没有实现,所以会报错:

./prog.go:29:11: cannot use p (variable of type *person) as type Tester in assignment:
    *person does not implement Tester (missing PrintData method)

报错提示没有实现Tester接口里面的PrintData方法。也就是说tester = p这块的赋值就不会成功了。
因为编译器扫描到这块赋值的时候,发现试着将*person类型赋值给tester时,需要检查*person类型是否完全实现了Tester接口。显然,编译器没有找到这个接口需要的PrintData方法,所以就会报错了。

错误二,参数类型需一致

如果我们将PrintData(info interface{})参数的类型修改为PrintData(info string),我们看下报错:

./prog.go:29:11: cannot use p (variable of type *person) as type Tester in assignment:
    *person does not implement Tester (wrong type for PrintData method)
        have PrintData(info string) error
        want PrintData(info interface{}) error

这个就是方法参数类型不一致导致,所以类型也需要一样的才可以

错误三,方法需全部实现

由于接口是属于双方的一种约定,那么其定义的方法,就需要全部的实现,这样才可以被正确的编译执行。现在我们在Tester接口中增加一个方法:

type Tester interface {
	PrintData(info interface{}) error
	//新增一个方法
	PrintData2() string
}

运行之后,将出现报错信息:

./prog.go:31:11: cannot use p (variable of type *person) as type Tester in assignment:
    *person does not implement Tester (missing PrintData2 method)

就会提示这个Tester接口还有一个PrintData2()方法没有被实现。

socket套接字

socket是一种套接字,对于新手来说,套接字可能不好理解,你可以将它看做一种特殊的文件,可以连接打开与读写,因为起源于Linux,而Linux是将任何东西或设备都当文件来对待,这样去看待就很容易理解了。

服务端:server.go

package main
import (
    "fmt"
    "log"
    "net"
    "bufio"
)
func handleConnection(conn net.Conn) {
	// 一直监听客户端的连接
	// 连接成功,如果客户端被强制中断,将报错:
	// 2022/11/05 11:37:05 客户端错误信息: read tcp 127.0.0.1:6010->127.0.0.1:3651: wsarecv: An existing connection was forcibly closed by the remote host.
    data, err := bufio.NewReader(conn).ReadString('\n')
    if err != nil {
        log.Fatal("客户端错误信息:", err)
    }
    fmt.Printf("%v", data)
    fmt.Fprintf(conn, "已连接到服务端\n")
    conn.Close()
}
func main() {
    ln, err := net.Listen("tcp", ":6010")
    if err != nil {
        panic(err)
    }
    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Fatal("客户端连接错误:", err)
        }
        go handleConnection(conn)
    }
}

客户端:client.go

package main
import (
    "fmt"
    "net"
    "bufio"
	"log"
)
func main() {
	// 客户端连接服务端,服务端的端口是6010
	// 如果没有连接上或服务端没有开启,将报错:
	// 2022/11/05 12:01:09 服务器拒绝服务:dial tcp :6010: connectex: No connection could be made because the target machine actively refused it.exit status 1
    conn, err := net.Dial("tcp", ":6010")
    if err != nil {
		log.Fatal("服务器拒绝服务:",err)
    }
	// 如果客户端连接成功,服务端反馈显示:客户端已连接
    fmt.Fprintf(conn, "客户端已连接\n")
    data, err := bufio.NewReader(conn).ReadString('\n')
    if err != nil {
        panic(err)
    }
    fmt.Printf("%v", data)
}

然后分别各自启动,就可以看到它们的连接状态了。


以下更多关于套接字的文章,多属于攻防方面,有兴趣的可以看下:

Python嗅探socket

Python的DoS拒绝服务之TCP/SYN洪水攻击

Python使用nmap进行端口扫描

Python遍历破解FTP密码,并上传webshell

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寅恪光潜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值