golang笔记(2)写一个简单的socket服务端
来源:互联网 发布:以色列 巴基斯坦 知乎 编辑:程序博客网 时间:2024/06/10 19:06
windows开发环境搭建http://blog.csdn.net/u010072711/article/details/72859731
一、概述
1.socket解读
2.socket与HTTP关系
3.socket与TCP/UDP关系
4.HTTP与TCP/UDP关系
二、第一步:绑定端口
//创建socket文件描述符,绑定ip:port,改变socket状态为监听状态netListen, err := net.Listen("tcp", "192.168.123.27:9800")//defer延迟关闭(方法返回的时候关闭)资源,以免引起内存泄漏defer netListen.Close()
这里的net.Listen方法为net包dial.go类中的一个方法。
第一个参数是制定网络IO类型,比如有TCP/IP, UDP, 域名解析, Unix domain socket
第二个参数是host:port 就是ip和端口号的组合。
第一个返回的的是当前连接socket状态监听器。
第二个返回是错误,我们可以判断,如果错误不为空就返回。
第一个返回的netListen是net.go类中的一个接口:
// A Listener is a generic network listener for stream-oriented protocols.//// Multiple goroutines may invoke methods on a Listener simultaneously.type Listener interface { // Accept waits for and returns the next connection to the listener. //从socket recive队列里获取一个建立好的连接 Accept() (Conn, error) // Close closes the listener. //关闭监听器 // Any blocked Accept operations will be unblocked and return errors. Close() error // Addr returns the listener's network address. //返回链接的传输类型和ip地址 Addr() Addr}
这个接口里的三个方法实现了对打开socket的三种基本操作,并在很多类中实现了这个接口,具体请看:
不同的具体链接都会实现这个接口,方便我们对socket链接做基本操作。
三、第二步:建立连接
conn, err := netListen.Accept() //第二步:获取连接
第一个返回 conn是当前socket链接。
第二个返回是错误,我们可以判断,如果错误不为空就返回。
第一个返回conn也是net.go类中的一个接口,源代码如下:
// Conn is a generic stream-oriented network connection.//// Multiple goroutines may invoke methods on a Conn simultaneously.type Conn interface { // Read reads data from the connection. // Read can be made to time out and return an Error with Timeout() == true // after a fixed time limit; see SetDeadline and SetReadDeadline. Read(b []byte) (n int, err error) // Write writes data to the connection. // Write can be made to time out and return an Error with Timeout() == true // after a fixed time limit; see SetDeadline and SetWriteDeadline. Write(b []byte) (n int, err error) // Close closes the connection. // Any blocked Read or Write operations will be unblocked and return errors. Close() error // LocalAddr returns the local network address. LocalAddr() Addr // RemoteAddr returns the remote network address. RemoteAddr() Addr // SetDeadline sets the read and write deadlines associated // with the connection. It is equivalent to calling both // SetReadDeadline and SetWriteDeadline. // // A deadline is an absolute time after which I/O operations // fail with a timeout (see type Error) instead of // blocking. The deadline applies to all future and pending // I/O, not just the immediately following call to Read or // Write. After a deadline has been exceeded, the connection // can be refreshed by setting a deadline in the future. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful Read or Write calls. // // A zero value for t means I/O operations will not time out. SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls // and any currently-blocked Read call. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error // SetWriteDeadline sets the deadline for future Write calls // and any currently-blocked Write call. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. // A zero value for t means Write will not time out. SetWriteDeadline(t time.Time) error}
我们可以看到里面有一系列的读写和关闭操作,就如上面说到的Listener 接口,也肯定是在很多具体的socket连接中被实现了,验证如下:
我们这里用的肯定是TCPConn了。
四、第三步:读写数据
上面我们也看到了,既然我们用的是TCPConn,也就是基于TCP的Socket链接。
里面的读写操作都已经实现了,我们直接调用就行了。
下面是socket服务端和客户端的交互过程:
其实里面的不管是客户端还是服务端,只要socket长链接建立成功了,我们读写都随便的,可先可后,具体看你的业务需求。
我们使用一个无限for循环来不断读写:
buffer := make([]byte, 2048) for { //无限循环 n, err := conn.Read(buffer) //第三步:读取从该端口传来的内容 //words := "ok" //向链接中写数据,向链接既可以先读也可以先写,看自己的需要 words := "golang socket server : " + strconv.Itoa(rand.Intn(100)) //向链接中写数据 conn.Write([]byte(words)) if err != nil { Log(conn.RemoteAddr().String(), " connection error: ", err) return //出错后返回 } Log(conn.RemoteAddr().String(), "receive data string:\n", string(buffer[:n])) }
五、服务端完整代码
package mainimport ( "fmt" "net" "log" "os" "math/rand" "strconv")func main() { //建立socket,监听端口 第一步:绑定端口 //netListen, err := net.Listen("tcp", "localhost:1024") netListen, err := net.Listen("tcp", "192.168.123.27:9800") CheckError(err) //defer延迟关闭改资源,以免引起内存泄漏 defer netListen.Close() Log("Waiting for clients") for { conn, err := netListen.Accept() //第二步:获取连接 if err != nil { continue //出错退出当前一次循环 } Log(conn.RemoteAddr().String(), " tcp connect success") //handleConnection(conn) //正常连接就处理 //这句代码的前面加上一个 go,就可以让服务器并发处理不同的Client发来的请求 go handleConnection(conn) //使用goroutine来处理用户的请求 }}//处理连接func handleConnection(conn net.Conn) { buffer := make([]byte, 2048) for { //无限循环 n, err := conn.Read(buffer) //第三步:读取从该端口传来的内容 //words := "ok" //向链接中写数据,向链接既可以先读也可以先写,看自己的需要 words := "golang socket server : " + strconv.Itoa(rand.Intn(100)) //向链接中写数据 conn.Write([]byte(words)) if err != nil { Log(conn.RemoteAddr().String(), " connection error: ", err) return //出错后返回 } Log(conn.RemoteAddr().String(), "receive data string:\n", string(buffer[:n])) }}//log输出func Log(v ...interface{}) { log.Println(v...)}//处理errorfunc CheckError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) }}
六、服务端完整代码
Github完整代码:https://github.com/Dawish/GoStudy/blob/master/src/main/SocketServer.go
- golang笔记(2)写一个简单的socket服务端
- 随手写了一个简单的socket服务端和客户端
- 一个简单的socket服务端Demo
- 一个简单的socket客户端和服务端的例子
- 一个简单的socket客户端和服务端的例子
- 分享一个PHP写的简单webservice服务端+客户端
- 一个PHP写的简单webservice服务端+客户端
- 建立一个服务端的SOCKET
- golang socket 服务端与客户端
- golang写的一套验证服务端以及web后台管理
- VC面向对象的方式 写一个基于TCP的 客户端服务端程序 (SOCKET)
- 用golang写的简单端口扫描器
- 一个极其简单的用golang net写的tcpip echoserver
- 用golang写的一个链表
- 一个简单的Php服务端
- 简单的Socket通信客户端和服务端
- 基于Socket简单的客户端-服务端例子
- 01 TCP Socket 编程_一个简单的服务端程序和客户端程序实现
- 解决MPAndroidChart-LineChart清除数据刷新后X轴取值不准确的问题
- 编写Java程序,计算数字可以被哪些数字整除。
- 构建配置文件
- adb shell 终止应用程序
- android 多媒体几个不错的博客
- golang笔记(2)写一个简单的socket服务端
- Java_内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别
- 迷宫问题
- linux 自动清除三天日志脚本
- Elasticsearch相关操作梳理
- ElasticSearch学习笔记(五)在logstash中配置分词器和同义词过滤器
- React构建单页应用方法与实例
- 1.2云存储标准的特性
- 排序之冒泡排序