(四十六)golang--网络编程(简易的聊天系统)
Go主要的目标之一就是面向大规模后端服务程序,网络通信这块是服务端程序必不可少也是至关键的一部分。
网络编程有两种:
(1)TCP Socket编程:是网络编程的主流,之所以叫TCP Socket编程,是因为底层是基于TCP/IP协议的;
(2)B/S结构的http编程,使用浏览器去访问服务器时,使用的就是http协议,而http底层就是tcp socket实现的;
计算机间需要通讯,必须要有网线、网卡或者是无线网卡;
TCP/IP模型:应用层、传输层、网络层、数据链路层、物理层;

IP地址:每个internet上的主机和路由器都有一个ip地址,它包括网络号和主机号,ip地址有ipv4(32位)或ipv6(128位),可以通过Ipconfig查看。
端口:逻辑意义上 的端口,特指tcp/ip协议中的端口。共256×256-1=65535个端口;
端口分类:
- 0是保留端口;
- 1-1024是固定端口(22:ssh远程登录协议,23:telnet使用,21:ftp使用,25:smtp服务使用,80:lis使用,7:echo服务)
- 1025-65535:是动态端口,供程序员使用;
服务端和客户端之间通信框图:

可以看出,它们之间的通信是通过端口 (由于是简易的通讯,目前客户端并不能直接交流,只能通过客户端)
server.go
package main import (
"fmt"
"net"
) func process(conn net.Conn) {
//这里接受客户端的数据
defer conn.Close()
for {
//创建一个新的切片
buf := make([]byte, )
//等待客户端发送信息,如果客户端没发送,协程就阻塞在这
// fmt.Printf("服务器在等待客户端%v的输入\n", conn.RemoteAddr().String())
n, err := conn.Read(buf)
if err != nil {
// fmt.Println("服务器read err=", err)
fmt.Println("客户端退出了")
return
}
//显示客户端发送内容到服务器的终端
fmt.Print(string(buf[:n]) + "\n") }
} func main() {
fmt.Println("服务器开始监听...")
//协议、端口
listen, err := net.Listen("tcp", "0.0.0.0:8888")
if err != nil {
fmt.Println("监听失败,err=", err)
return
}
//延时关闭
defer listen.Close()
for {
//循环等待客户端连接
fmt.Println("等待客户端连接...")
conn, err := listen.Accept()
if err != nil {
fmt.Println("Accept() err=", err)
} else {
fmt.Printf("Accept() suc con=%v,客户端Ip=%v\n", conn, conn.RemoteAddr().String())
}
//这里准备起个协程为客户端服务
go process(conn)
}
//fmt.Printf("监听成功,suv=%v\n", listen)
}
client.go
package main import (
"bufio"
"fmt"
"net"
"os"
"strings"
) func main() {
//同样是tcp协议,192.168.1.145服务端的ip地址,这里是我自己本机的地址,可在终端用ipconfig查看,后面是服务端开启的端口号
conn, err := net.Dial("tcp", "192.168.1.145:8888")
if err != nil {
fmt.Println("client dial err=", err)
return
}
//哭护短在命令行输入单行数据
reader := bufio.NewReader(os.Stdin)
for {
//从终端读取一行用户的输入,并发给服务器
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println("readString err=", err)
}
//去掉输入后的换行符
line = strings.Trim(line, "\r\n")
//如果是exit,则退出客户端
if line == "exit" {
fmt.Println("客户端退出了")
break
}
//将line发送给服务器
_, e := conn.Write([]byte(line))
if e != nil {
fmt.Println("conn.write err=", e)
}
// fmt.Printf("客户端发送了%d字节的数据,并退出", n)
}
}
首先在一个终端打开服务器:

然后连接两个客户端:


注意到,每个客户端的端口号是不一致的:

然后两个客户端分别发送消息给服务端:


服务端可以接收到信息:

最后输入exit分别关闭两个客户端:



两个客户端都退出了,然后服务端继续等待新的客户端的连接。
(四十六)golang--网络编程(简易的聊天系统)的更多相关文章
- Python学习笔记(四十六)网络编程(2)— UDP编程
摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320049779 ...
- Python学习笔记(四十五)网络编程(1)TCP编程
摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320043745 ...
- Android简易实战教程--第四十六话《RecyclerView竖向和横向滚动》
Android5.X后,引入了RecyclerView,这个控件使用起来非常的方便,不但可以完成listView的效果,而且还可以实现ListView无法实现的效果.当然,在新能方便也做了大大的提高. ...
- JAVA第十周《网络编程》学习内容总结
JAVA第十周<网络编程>学习内容总结 学习内容总结 1.初听到网络编程四个字可能会觉得很困难,实际上网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据,把数据发送到指定的位置, ...
- NeHe OpenGL教程 第四十六课:全屏反走样
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 四十六、android中的Bitmap
四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android ...
- python---基础知识回顾(六)网络编程2(处理粘包)
前戏: 之前在python---基础知识回顾(六)网络编程异步模块中提到过粘包现象,而且在使用twisted中提到过一种处理办法,按行接收lineReceived,当收到\r\n换行符时,才去缓冲区中 ...
- “全栈2019”Java第四十六章:继承与字段
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期
欢迎访问我的个人网站获取更佳阅读排版 golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期 | yoko blog (https://pengrl.com/p/47401/) 本篇文章部 ...
- 第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么
第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么 Sigma协议 Sigma协议是Alice想要向Bob证明一些东西的协议(Alice知道一些秘密).他们有下面的一般范式:Al ...
随机推荐
- Leetcode Tags(5)Hash Table
一.500. Keyboard Row 给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词. 输入: ["Hello", "Alaska", &q ...
- Python基础入门总结
Python基础入门教学 基础中的基础 列表.元组(tuple).字典.字符串 变量和引用 函数 python视频教程下载 基础中的基础 解释型语言和编译型语言差距: Python概述 解释器执行原理 ...
- SVM详细笔记及总结
本文精品,如有疑问欢迎留言or微信咨询:523331232
- kaldi中CD-DNN-HMM网络参数更新公式手写推导
在基于DNN-HMM的语音识别中,DNN的作用跟GMM是一样的,即它是取代GMM的,具体作用是算特征值对每个三音素状态的概率,算出来哪个最大这个特征值就对应哪个状态.只不过以前是用GMM算的,现在用D ...
- Android H5混合开发(1):构建Cordova 项目
Cordova是什么 Apache Cordova是一个开源的移动开发框架.允许你用标准的web技术-HTML5,CSS3和JavaScript做跨平台开发. 以移动平台为例,安卓.IOS平台设备的常 ...
- 10、pytest -- skip和xfail标记
目录 1. 跳过测试用例的执行 1.1. @pytest.mark.skip装饰器 1.2. pytest.skip方法 1.3. @pytest.mark.skipif装饰器 1.4. pytest ...
- html获得当前日期
<html> <head> <title> </title> </head> <body> <!-- 获得当前日期(年月日 ...
- [开源] gnet: 一个轻量级且高性能的 Golang 网络库
Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Ev ...
- C++ 11新标准实现POJ No.1001-Exponentiation
Exponentiation(高精度幂计算)(标签:链表,字符串,快速幂计算) 题目描述 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解 ...
- Linux JDK 安装与配置
一.下载 JDK 官网链接:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 系 ...