发现电脑上装着liteide,就用golang做一个TCP通讯测试(支持先启动client端和断线重连)
1、参考https://www.cnblogs.com/yin5th/p/9274495.html
server端 main.go
package main import (
"fmt"
"net"
) func main() {
// simple tcp server
//1.listen ip+port
listener, err := net.Listen("tcp", "0.0.0.0:9090")
if err != nil {
fmt.Printf("listen fail, err: %v\n", err)
return
} //2.accept client request
//3.create goroutine for each request
for {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("accept fail, err: %v\n", err)
continue
} //create goroutine for each connect
go process(conn)
}
} func process(conn net.Conn) {
defer conn.Close()
for {
var buf []byte
n, err := conn.Read(buf[:]) if err != nil {
fmt.Printf("read from connect failed, err: %v\n", err)
break
}
str := string(buf[:n])
fmt.Printf("receive from client, data: %v\n", str)
}
}
client端 main.go
package main import (
"bufio"
"fmt"
"net"
"os"
"strings"
) func main() {
conn, err := net.Dial("tcp", "localhost:9090")
defer conn.Close()
if err != nil {
fmt.Printf("connect failed, err : %v\n", err.Error())
return
} inputReader := bufio.NewReader(os.Stdin) for {
input, err := inputReader.ReadString('\n')
if err != nil {
fmt.Printf("read from console failed, err: %v\n", err)
break
}
trimmedInput := strings.TrimSpace(input)
if trimmedInput == "Q" {
break
}
_, err = conn.Write([]byte(trimmedInput)) if err != nil {
fmt.Printf("write failed , err : %v\n", err)
break
}
}
}
2.想要交互的话,只需在c/s两端的循环中适时用conn.Read 和conn.Write,用fmt.Printf显示出来即可
3、golang []byte和string相互转换 参考 https://www.cnblogs.com/DaBing0806/p/6680750.html
4,golang 几种字符串的连接方式 参考 https://blog.csdn.net/hatlonely/article/details/79156311 和https://studygolang.com/articles/3427
4、不想出现dos窗口的话 ,参考:https://blog.csdn.net/wangkai_123456/article/details/71158341
配置: go build -ldflags "-H windowsgui"
lite IDE配置
菜单 编译→编译配置
在“自定义”页面下的 BUILDAGRS 后添加 -ldflags "-H windowsgui"
5、不是本机测试的话,服务器端口参考https://blog.csdn.net/yoie01/article/details/21488457
如果只作为本地测试的话,可以写成loaclhost:xxxx
如果是监听外网的话,则直接写端口即可 :XXXX
注意添加防火墙入站规则。允许所有程序,指定本地特定端口,协议,远程所有端口。
6,为解决断线重连问题,参考https://blog.csdn.net/mypc2010/article/details/78276702
将server端改为
//服务端反向控制
package main import (
"bytes"
"fmt"
"net"
) func main() {
//监听
listener, err := net.Listen("tcp", ":9097")
if err != nil {
fmt.Printf("listen fail, err: %v\n", err)
return
}
//循环,接受和处理
for {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("accept fail, err: %v\n", err)
continue
}
//在goroutine中处理
go process(conn)
}
} func process(conn net.Conn) {
defer conn.Close()
for {
//先向管道中写数据
var buffer bytes.Buffer
buffer.WriteString("i am server,ip: ")
buffer.WriteString(LocalIp())
ipa := buffer.String()
conn.Write([]byte(ipa))
//再从管道中读数据
var buf []byte
n, err := conn.Read(buf[:])
if err != nil {
fmt.Printf("read from connect failed, err: %v\n", err)
break
}
str := string(buf[:n])
fmt.Printf("received from client, data: %v\n", str)
}
} //显示本机IP
func LocalIp() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
fmt.Println(err)
}
var ip string = "localhost"
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
ip = ipnet.IP.String()
}
}
}
return ip
}
将client端改为
//client
package main import (
"bytes"
"errors"
"fmt"
"net"
"os"
"time"
) func main() {
for {
conn, err := net.Dial("tcp", "192.168.0.239:9097")
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
} else {
defer conn.Close()
doWork(conn)
} time.Sleep( * time.Second)
}
}
//显示本机IP
func LocalIp() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
fmt.Println(err)
}
var ip string = "localhost"
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
ip = ipnet.IP.String()
}
}
}
return ip
} //接收服务端发来的消息
func ClientMsgHandler(conn net.Conn, ch chan int) { var buf []byte
n, _ := conn.Read(buf[:])
str := string(buf[:n])
fmt.Printf("cmd from S, data: %v\n", str)
if len(str) == {
//服务端无返回信息
ch <-
}
//reply to server
var buffer bytes.Buffer
buffer.WriteString("i received,i am clent ip: ")
buffer.WriteString(LocalIp())
str2 := buffer.String()
data2 := []byte(str2)
conn.Write(data2)
} //解决断线重连问题
func doWork(conn net.Conn) error { ch := make(chan int, ) ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case stat := <-ch:
if stat == {
return errors.New("None Msg")
}
case <-ticker.C:
ch <-
go ClientMsgHandler(conn, ch) case <-time.After(time.Second * ):
defer conn.Close()
fmt.Println("timeout")
} } return nil
}
可先启动多个client,再启动server,且断线重连。
发现电脑上装着liteide,就用golang做一个TCP通讯测试(支持先启动client端和断线重连)的更多相关文章
- 在电脑上装ubuntu12.04系统,内核文件是那个?
在电脑上装ubuntu12.04系统,我们能看到的是根文件系统,那么内核文件(zlmage)是那个? ???
- 【Golang 接口自动化00】为什么要用Golang做自动化?
为什么使用Golang做自动化 顺应公司的趋势学习了Golang之后,因为没有开发那么多的时间和项目来实践,怕步此前学习Java缺少练习遗忘殆尽的后尘,决定利用工作之余的时间把此前用Python的写的 ...
- 使用golang写一个redis-cli
使用golang写一个redis-cli 0. redis通信协议 redis的客户端(redis-cli)和服务端(redis-server)的通信是建立在tcp连接之上, 两者之间数据传输的编码解 ...
- 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。
最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...
- Golang做的验证码(2)
前面一篇文章介绍了2个用Golang做的验证码 http://www.cnblogs.com/ghj1976/p/3392847.html 这里再补充几个: 1.在GAE上使用的Google的验证码 ...
- golang(5):编写WebSocket服务,client和html5调用
本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46882777 转载请必须注明出处! 1.关于websocket HTML5定义了 ...
- golang实现一个代理服务器(proxy)学习笔记
golang是google公司开发一门新的编程语言.对于老的程序员来说,学习一门语言最好的方式,不过是做一个小的项目. 网上看到这一篇使用golang开发proxy的例子,觉得挺有意思.希望通过实际模 ...
- 今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的解决了这个问题。
今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的 ...
- 如何使用Golang实现一个API网关
你是否也存在过这样的需求,想要公开一个接口到网络上.但是还得加点权限,否则被人乱调用就不好了.这个权限验证的过程,最好越简单越好,可能只是对比两个字符串相等就够了.一般情况下我们遇到这种需要,就是在函 ...
随机推荐
- 网页字体在Frontpage2000制作网页中的讲解
运用HTML,我们可以对字体的大小及字形进行简单的修改,但要进行统一地控制.创建特殊效果,就必须要用到CSS.它能让您更有效地控制网页外观,并可以扩充精确指定网页元素位置,外观以及创建特殊效果的能力. ...
- K8s helm 创建自定义Chart
# 删除之前创建的 chart helm list helm delete --purge redis1 # 创建自定义 chart myapp cd ~/helm helm create myapp ...
- Web前端开发必备
前端学习相关书籍 关于书籍 HTML.CSS 类别书籍,都是大同小异,在当当网.卓越网搜索一下很多推荐.如果感觉学的差不多了,可以关注一下<CSS禅意花园>,这个很有影响力. Javasc ...
- java方法中,传参是传值还是传址问题(对比C语言、C#和C++)
问题引出: 编写一个简单的交换值的小程序,如果我们只是简单地定义一个交换函数接收两个数,在函数内部定义一个中间变量完成交换.那么当我们把a,b两个实参传给这个函数时,往往得不到预期的结果.这是为什么呢 ...
- viewPager+fragment如何刷新缓存fragment
最近在做一个项目,有一个功能是答题翻页.于是需要实现在这一页的时候就缓存下一页. 刚刚开始我是用 setOnPageChangeListener方法监听,滑到这一页的时候才刷新这一页: public ...
- mac 苹果多版本jdk自由切换
场景 手头上的工具有时候依赖低版本jdk,有时候需要高版本jdk, 如何在不同版本jdk之间来回自由的切换? 安装 首选需要去官网下载dmg安装包,地址:https://www.oracle.com/ ...
- HandyEditor 富文本编辑器整合到python flask项目中
1.下载HandyEditor,地址http://he.catfish-cms.com/ 2.解压后的文件名HandyEditor-master改为HandyEditor,文件夹里的文件如下 3.将H ...
- 简易付XP版本无法获取server.xml配置文件处理方案
博客地址:https://blog.csdn.net/zdw_wym/article/details/40892535 把它添加到C:/WINDOWS/Microsoft.NET/Framework/ ...
- Spring(mvc)思维导图
spring mvc简介与运行原理 Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器 ...
- [20190101]块内重整.txt
[20190101]块内重整.txt --//我不知道用什么术语表达这样的情况,我仅仅一次开会对方这么讲,我现在也照用这个术语.--//当dml插入数据到数据块时,预留一定的空间(pctfree的百分 ...