Golang socket
1.本例子实现了一个简单的TCP echo。客户端发送Hello,服务端回应World。
参考:《Socket编程》
2.服务端代码
package main import (
"net"
"fmt"
"os"
"time"
) //错误处理函数
func checkErr(err error, extra string) bool {
if err != nil {
formatStr := " Err : %s\n";
if extra != "" {
formatStr = extra + formatStr;
} fmt.Fprintf(os.Stderr, formatStr, err.Error());
return true;
} return false;
} //连接处理函数
func svrConnHandler(conn net.Conn) {
fmt.Println("Client connect success :", conn.RemoteAddr().String());
conn.SetReadDeadline(time.Now().Add( * time.Minute))
request := make([]byte, );
defer conn.Close();
for {
readLen, err := conn.Read(request)
if checkErr(err, "Read") {
break;
} //socket被关闭了
if readLen == {
fmt.Println("Client connection close!");
break;
} else {
//输出接收到的信息
fmt.Println(string(request[:readLen])) time.Sleep(time.Second);
//发送
conn.Write([]byte("World !"));
} request = make([]byte, );
}
} func main() {
//解析地址
tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:6666");
if checkErr(err, "ResolveTCPAddr") {
return;
} //设置监听地址
listener, err := net.ListenTCP("tcp", tcpAddr);
if checkErr(err, "ListenTCP") {
return;
} for {
//监听
fmt.Println("Start wait for client.")
conn, err := listener.Accept();
if checkErr(err, "Accept") {
continue;
} //消息处理函数
go svrConnHandler(conn);
}
}
3.客户端代码
package main import (
"fmt"
"os"
"net"
"sync"
) var gLocker sync.Mutex; //全局锁
var gCondition *sync.Cond; //全局条件变量 //错误处理函数
func checkErr(err error, extra string) bool {
if err != nil {
formatStr := " Err : %s\n";
if extra != "" {
formatStr = extra + formatStr;
} fmt.Fprintf(os.Stderr, formatStr, err.Error());
return true;
} return false;
} //连接处理函数
func clientConnHandler(conn net.Conn) {
gLocker.Lock();
defer gLocker.Unlock(); defer conn.Close(); request := make([]byte, );
for {
readLen, err := conn.Read(request)
if checkErr(err, "Read") {
gCondition.Signal();
break;
} //socket被关闭了
if readLen == {
fmt.Println("Server connection close!"); //条件变量同步通知
gCondition.Signal();
break;
} else {
//输出接收到的信息
fmt.Println(string(request[:readLen])) //发送
conn.Write([]byte("Hello !"));
} request = make([]byte, );
}
} func main() {
//解析地址
tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:6666");
if checkErr(err, "ResolveTCPAddr") {
return;
} conn, err := net.DialTCP("tcp", nil, tcpAddr);
if checkErr(err, "DialTCP") {
return;
} fmt.Println("Connect server success.") gLocker.Lock();
gCondition = sync.NewCond(&gLocker); //发送数据给服务器
conn.Write([]byte("Hello !")); //处理连接(lock在上面调用了,所以clientConnHandler函数必须等wait函数调用后才能lock,这样就能保证调用的先后顺序)
go clientConnHandler(conn); //主线程阻塞,等待Singal结束
for {
//条件变量同步等待
gCondition.Wait();
break;
}
gLocker.Unlock();
fmt.Println("Client finish.")
}
PS:关于sync.Cond可以参考下一篇文章:《Golang sync》
4.结果截图

以上。
Golang socket的更多相关文章
- golang socket 分析
socket:tcp/udp.ip构成了网络通信的基石,tcp/ip是面向连接的通信协议 要求建立连接时进行3次握手确保连接已被建立,关闭连接时需要4次通信来保证客户端和,服务端都已经关闭 在通信过程 ...
- golang socket 实现分析(一)
socket:tcp/udp.ip构成了网络通信的基石,tcp/ip是面向连接的通信协议 要求建立连接时进行3次握手确保连接已被建立,关闭连接时需要4次通信来保证客户端和,服务端都已经关闭 在通信过程 ...
- golang socket与Linux socket比较分析
在posix标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带runtime的跨平台编程语言,Go中提供给开发者的socket API是建立在操作系统原生socket ...
- Linux下Golang Socket编程原理分析与代码实现
在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...
- [转] golang socket
server.go package main import ( "net" "fmt" "io/ioutil" "time&quo ...
- Golang Socket编程
Socket编程 在很多底层网络应用开发者的眼里一切编程都是Socket,话虽然有点夸张,但却也几乎如此了,现在的网络编程几乎都是用Socket来编程.你想过这些情景么?我们每天打开浏览器浏览网页时, ...
- golang socket编程 net.Conn IO.EOF解读
结论 首先,先定义下我的理解,当在Read时,收到一个IO.EOF,代表的就是对端已经关闭了发送的通道,通常来说是发起了FIN. 那么根据自己的实际业务,就可以进行判断,这里的IO.EOF到底该怎么利 ...
- Golang websocket
环境:Win10 + Go1.9.2 1.先下载并引用golang的websocket库 ①golang的官方库都在https://github.com/golang下,而websocket库在/ne ...
- Golang开发支持平滑升级(优雅重启)的HTTP服务
Golang开发支持平滑升级(优雅重启)的HTTP服务 - tabalt的博客 http://tabalt.net/blog/graceful-http-server-for-golang/ http ...
随机推荐
- Java操作文件Util
package io.guangsoft.utils; import java.io.File; import java.io.FileInputStream; import java.io.File ...
- jtl转化成CSV格式的聚合报告
1: 从官网下载4.0 的zip 包解压缩,下载地址: https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-4.0.zip ,假 ...
- Navicat Premium 12.0.18安装与激活(转)
转载:https://www.jianshu.com/p/42a33b0dda9c 一.Navicat Premium 12下载 Navicat Premium 12是一套数据库开发管理工具,支持连接 ...
- 【python014--字符串内置函数】
一.实现跨越多行的字符串 1.采用双引号实现 str1 = ""待我长发及腰,将军归来可好?此身君子意逍遥,怎料山河萧萧天光乍破遇,暮雪白头老寒剑默听奔雷,长枪独守空豪醉卧沙场君莫 ...
- Restful framework【第九篇】分页器
基本使用 分页 -简单分页 page_size = api_settings.PAGE_SIZE :每页显示条数 page_query_param = 'page' :查询的页码数 page_size ...
- minicom支持向串口自动发送命令的功能
1. 用法 minicom -S <script name> -C <log name> 参数解析: -S: 指定要执行的脚本 -C: 指定输出日志文件名 2. 既然可以指定脚 ...
- 分布式事务框架&解决方案参考
两种开源解决方案框架介绍: https://blog.csdn.net/zyndev/article/details/79604395#_97 LCN: https://www.jianshu.com ...
- CF776B Sherlock and his girlfriend
题目地址 题目链接 题解 这题很有意思啊qwq.本来是写算出每个数的质约数的,然后写到一半发现,质约数互相不影响,有质约数的数肯定是合数. 所以合数染一种色,质数染一种色就好 #include < ...
- 案例1:写一个压缩字符串的方法,例如aaaabbcxxx,则输出a4b2c1x3。
public static String zipString(String str){ String result = "";//用于拼接新串的变量 char last = str ...
- zepto 入门
2017-03-17 文章来源:http://www.cnblogs.com/daysme zepto 简介 jq虽然有一些衍生的插件可用在移动端上,但它有点大. click 有,但有问题 onmou ...