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 ...
随机推荐
- 探索RequestBody报com.alibaba.fastjson.JSONObject cannot be cast to xxx
今天使用RequestBody接受前端传过来的参数,以前接受字符串数组非常成功,这次把形参改成了List<User>,原本以为顺利接受参数并映射成User的list结构,结果竟然在我取us ...
- ORA-00600: internal error code, arguments: [13030], [20]一例解决
两年没有接触oracle了,中午,一环境update from的时候出现ORA-00600: internal error code, arguments: [13030], [20]异常,经查,官网 ...
- 一个简单的购物金额结算(JAVA)
我编写的代码: import java.util.Scanner; public class ZuoYe01 { public static void main(String[] args) { // ...
- mvc 前端校验
首先解决 Ajax.BeginFor异步提交表单,给表单添加样式的问题.不能直接用class属性,网上找了很多都是用ClassName,经过测试不管用,看源代码发现生成的是ClassName而非cla ...
- 关于A left join B,A是否一定是主表?
一般情况,我们作左连接 select * from A left join B on A.id=B.a_id;一定认为A就是主表,其实还有另外的情况,我们若将sql改写成 select * from ...
- opencv学习之路(6)、鼠标截图,滑动条播放视频
一.鼠标截图 #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespa ...
- 什么是TF-A?
1. TF-A的全称是什么? Arm Trusted Firmware 2. TF-A的作用是什么? 在secure world和non-secure world之间切换 3. TF-A涉及到哪几个部 ...
- Git学习笔记---安装与初始化 连接远程版本库
1.Git的安装 sudo apt-get install git 用的是linux(ubuntu)系统,安装非常简单,上面一条命令就够了. 2.初次运行的配置 Git 提供了一个叫做 git con ...
- codevs1017乘积最大
codevs1017 乘积最大 题目描述 Description 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场 ...
- ActiveMQ安装使用
入门: https://www.cnblogs.com/cyfonly/p/6380860.html http://www.uml.org.cn/zjjs/201802111.asp https:// ...