go语言写CS Go语言写辅助

如何在golang 中调用c的静态库或者动态库

Cgo 使得Go程序能够调用C代码. cgo读入一个用特别的格式写的Go语言源文件, 输出Go和C程序, 使得C程序能打包到Go语言的程序包中.

创新互联专注于休宁县网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供休宁县营销型网站建设,休宁县网站制作、休宁县网页设计、休宁县网站官网定制、小程序定制开发服务,打造休宁县网络公司原创品牌,更为您提供休宁县网站排名全网营销落地服务。

举例说明一下. 下面是一个Go语言包, 包含了两个函数 -- Random 和 Seed -- 是C语言库中random和srandom函数的马甲.

package rand

/*

#include stdlib.h

*/ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) }

我们来看一下这里都有什么内容. 开始是一个包的导入语句.

rand包导入了"C"包, 但你会发现在Go的标准库里没有这个包. 那是因为C是一个"伪包", 一个为cgo引入的特殊的包名, 它是C命名空间的一个引用.

rand 包包含4个到C包的引用: 调用 C.random和C.srandom, 类型转换 C.uint(i)还有引用语句.

Random函数调用libc中的random函数, 然后回返结果. 在C中, random返回一个C类型的长整形值, cgo把它轮换为C.long. 这个值必需转换成Go的类型, 才能在Go程序中使用. 使用一个常见的Go类型转换:

func Random() int { return int(C.random()) }

这是一个等价的函数, 使用了一个临时变量来进行类型转换:

func Random() int { var r C.long = C.random() return int(r) }

Seed函数则相反. 它接受一个Go语言的int类型, 转换成C语言的unsigned int类型, 然后传递给C的srandom函数.

func Seed(i int) { C.srandom(C.uint(i)) }

需要注意的是, cgo中的unsigned int类型写为C.uint; cgo的文档中有完整的类型列表.

这个例子中还有一个细节我们没有说到, 那就是导入语句上面的注释.

/*

#include stdlib.h

*/ import "C"

Cgo可以识别这个注释, 并在编译C语言程序的时候将它当作一个头文件来处理. 在这个例子中, 它只是一个include语句, 然而其实它可以是使用有效的C语言代码. 这个注释必需紧靠在import "C"这个语句的上面, 不能有空行, 就像是文档注释一样.

Strings and things

与Go语言不同, C语言中没有显式的字符串类型. 字符串在C语言中是一个以0结尾的字符数组.

Go和C语言中的字符串转换是通过C.CString, C.GoString,和C.GoStringN这些函数进行的. 这些转换将得到字符串类型的一个副本.

下一个例子是实现一个Print函数, 它使用C标准库中的fputs函数把一个字符串写到标准输出上:

package print // #include stdio.h // #include stdlib.h import "C" import "unsafe" func Print(s string) { cs := C.CString(s) C.fputs(cs, (*C.FILE)(C.stdout)) C.free(unsafe.Pointer(cs)) }

在C程序中进行的内存分配是不能被Go语言的内存管理器感知的. 当你使用C.CString创建一个C字符串时(或者其它类型的C语言内存分配), 你必需记得在使用完后用C.free来释放它.

调用C.CString将返回一个指向字符数组开始处的指错, 所以在函数退出前我们把它转换成一个unsafe.Pointer(Go中与C的void 等价的东西), 使用C.free来释放分配的内存. 一个惯用法是在分配内存后紧跟一个defer(特别是当这段代码比较复杂的时候), 这样我们就有了下面这个Print函数:

func Print(s string) { cs := C.CString(s) defer C.free(unsafe.Pointer(cs)) C.fputs(cs, (*C.FILE)(C.stdout)) }

构建 cgo 包

如果你使用goinstall, 构建cgo包就比较容易了, 只要调用像平常一样使用goinstall命令, 它就能自动识别这个特殊的import "C", 然后自动使用cgo来编译这些文件.

如果你想使用Go的Makefiles来构建, 那在CGOFILES变量中列出那些要用cgo处理的文件, 就像GOFILES变量包含一般的Go源文件一样.

rand包的Makefile可以写成下面这样:

include $(GOROOT)/src/Make.inc

TARG=goblog/rand

CGOFILES=\ rand.go\ include $(GOROOT)/src/Make.pkg

然后输入gomake开始构建.

更多 cgo 的资源

cgo的文档中包含了关于C伪包的更多详细的说明, 以及构建过程. Go代码树中的cgo的例子给出了更多更高级的用法.

一个简单而又符合Go惯用法的基于cgo的包是Russ Cox写的gosqlite. 而Go语言的网站上也列出了更多的的cgo包.

最后, 如果你对于cgo的内部是怎么运作这个事情感到好奇的话, 去看看运行时包的cgocall.c文件的注释吧.

为什么要使用 Go 语言?Go 语言的优势在哪里?

1、简单易学。

Go语言的作者本身就很懂C语言,所以同样Go语言也会有C语言的基因,所以对于程序员来说,Go语言天生就会让人很熟悉,容易上手。

2、并发性好。

Go语言天生支持并发,可以充分利用多核,轻松地使用并发。 这是Go语言最大的特点。

描述

Go的语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能。Go的并行模型是以东尼·霍尔的通信顺序进程(CSP)为基础,采取类似模型的其他语言包括Occam和Limbo,但它也具有Pi运算的特征,比如通道传输。

在1.8版本中开放插件(Plugin)的支持,这意味着现在能从Go中动态加载部分函数。

与C++相比,Go并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收、接口(Interface)等特性的语言级支持。

Go 语言自我提升 (三次握手 - 四次挥手 - TCP状态图 - udp - 网络文件传输)

三次握手:

1. 主动发起连接请求端(客户端),发送 SYN 标志位,携带数据包、包号

2. 被动接收连接请求端(服务器),接收 SYN,回复 ACK,携带应答序列号。同时,发送SYN标志位,携带数据包、包号

3. 主动发起连接请求端(客户端),接收SYN 标志位,回复 ACK。

被动端(服务器)接收 ACK —— 标志着 三次握手建立完成( Accept()/Dial() 返回 )

四次挥手:

1. 主动请求断开连接端(客户端), 发送 FIN标志,携带数据包

2. 被动接受断开连接端(服务器), 发送 ACK标志,携带应答序列号。 —— 半关闭完成。

3. 被动接受断开连接端(服务器), 发送 FIN标志,携带数据包

4. 主动请求断开连接端(客户端), 发送 最后一个 ACK标志,携带应答序列号。—— 发送完成,客户端不会直接退出,等 2MSL时长。

等 2MSL待目的:确保服务器 收到最后一个ACK

滑动窗口:

通知对端本地存储数据的 缓冲区容量。—— write 函数在对端 缓冲区满时,有可能阻塞。

TCP状态转换:

1. 主动发起连接请求端:

CLOSED —— 发送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回发 ACK —— ESTABLISHED (数据通信)

2. 主动关闭连接请求端:

ESTABLISHED —— 发送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半关闭、主动端)

—— 接收FIN、回复ACK —— TIME_WAIT (主动端) —— 等 2MSL 时长 —— CLOSED

3. 被动建立连接请求端:

CLOSED —— LISTEN —— 接收SYN、发送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (数据通信)

4. 被动断开连接请求端:

ESTABLISHED —— 接收 FIN、发送 ACK —— CLOSE_WAIT —— 发送 FIN —— LAST_ACK —— 接收ACK —— CLOSED

windows下查看TCP状态转换:

netstat -an | findstr  端口号

Linux下查看TCP状态转换:

netstat -an | grep  端口号

TCP和UDP对比: 

TCP: 面向连接的可靠的数据包传递。 针对不稳定的 网络层,完全弥补。ACK

UDP:无连接不可靠的报文传输。 针对不稳定的 网络层,完全不弥补。还原网络真实状态。

优点                                                             缺点

TCP: 可靠、顺序、稳定                                      系统资源消耗大,程序实现繁复、速度慢

UDP:系统资源消耗小,程序实现简单、速度快                          不可靠、无序、不稳定

使用场景:

TCP:大文件、可靠数据传输。 对数据的 稳定性、准确性、一致性要求较高的场合。

UDP:应用于对数据时效性要求较高的场合。 网络直播、电话会议、视频直播、网络游戏。

UDP-CS-Server实现流程:

1.  创建 udp地址结构 ResolveUDPAddr(“协议”, “IP:port”) —— udpAddr 本质 struct{IP、port}

2.  创建用于 数据通信的 socket ListenUDP(“协议”, udpAddr ) —— udpConn (socket)

3.  从客户端读取数据,获取对端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err

4.  发送数据包给 客户端 udpConn.WriteToUDP("数据", clientAddr)

UDP-CS-Client实现流程:

1.  创建用于通信的 socket。 net.Dial("udp", "服务器IP:port") —— udpConn (socket)

2.  以后流程参见 TCP客户端实现源码。

UDPserver默认就支持并发!

------------------------------------

命令行参数: 在main函数启动时,向整个程序传参。 【重点】

语法: go run xxx.go   argv1 argv2  argv3  argv4 。。。

xxx.exe:  第 0 个参数。

argv1 :第 1 个参数。

argv2 :第 2 个参数。

argv3 :第 3 个参数。

argv4 :第 4 个参数。

使用: list := os.Args  提取所有命令行参数。

获取文件属性函数:

os.stat(文件访问绝对路径) —— fileInfo 接口

fileInfo 包含 两个接口。

Name() 获取文件名。 不带访问路径

Size() 获取文件大小。

网络文件传输 —— 发送端(客户端)

1.  获取命令行参数,得到文件名(带路径)filePath list := os.Args

2.  使用 os.stat() 获取 文件名(不带路径)fileName

3.  创建 用于数据传输的 socket  net.Dial("tcp", “服务器IP+port”) —— conn

4.  发送文件名(不带路径)  给接收端, conn.write()

5.  读取 接收端回发“ok”,判断无误。封装函数 sendFile(filePath, conn) 发送文件内容

6.  实现 sendFile(filePath,  conn)

1) 只读打开文件 os.Open(filePath)

for {

2) 从文件中读数据  f.Read(buf)

3) 将读到的数据写到socket中  conn.write(buf[:n])

4)判断读取文件的 结尾。 io.EOF. 跳出循环

}

网络文件传输 —— 接收端(服务器)

1. 创建用于监听的 socket net.Listen() —— listener

2. 借助listener 创建用于 通信的 socket listener.Accpet()  —— conn

3. 读取 conn.read() 发送端的 文件名, 保存至本地。

4. 回发 “ok”应答 发送端。

5. 封装函数,接收文件内容 recvFile(文件路径)

1) f = os.Create(带有路径的文件名)

for {

2)从 socket中读取发送端发送的 文件内容 。 conn.read(buf)

3)  将读到的数据 保存至本地文件 f.Write(buf[:n])

4)  判断 读取conn 结束, 代表文件传输完成。 n == 0  break

}

go 语言可以写C/s编程语言吗?我看到都是web编程也就是B/S

语言只是工具而已,有的适合做哪一方面。

一般来说高级语言除了写底层的东西,什么都能做。

go语言听说过但不了解

我想应该像python

ruby一样吧

拿python来说,可以写web,可以写socket,数据库,game,图形界面,你去官网看看他能做什么在右边的最下面有,几乎什么都能做。

所以go语言开发cs架构肯定是可以的,不知道适合不适合。


当前文章:go语言写CS Go语言写辅助
当前网址:http://pwwzsj.com/article/hppsgp.html