Go语言net模块TCP和UDP编程实践

news2025/1/24 1:42:59

任何一种语言TCP和UDP网络编程总是必须的,接下来就将go语言中使用net标准库进行TCP和UDP编程进行梳理总结。

目录

1.代码结构

2.TCP通信

3.UDP通信

4.TCP模拟HTTP协议通信

5.利用TCP扫描那些端口被占用


1.代码结构

2.TCP通信

server.go

package main

import (
	"fmt"
	"net"
)

func main() {
	//1.监听端口
	listen, err := net.Listen("tcp", "0.0.0.0:18383")
	if err != nil {
		fmt.Println("listen failed, err:", err)
		return
	}

	fmt.Println("listen Start...")

	for {
		//2.接收客户端连接
		conn, err := listen.Accept()
		if err != nil {
			fmt.Printf("accept failed, err:%v\n", err)
			continue
		}
		//3.开启Goroutine处理连接
		go process(conn)
	}
}

// 处理请求,类型就是net.Conn
func process(conn net.Conn) {

	//处理结束后关闭链接
	defer conn.Close()
	for {
		var buf [128]byte
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Printf("read from conn failed, err: %v", err)
			break
		}
		fmt.Printf("recv from client, content: %v\n", string(buf[:n]))
	}

}

client.go

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

func main() {
	conn, err := net.Dial("tcp", "0.0.0.0:18383")
	if err != nil {
		fmt.Printf("dial failed, err: %v\n", err)
		return
	}

	fmt.Println("conn established...")

	reader := bufio.NewReader(os.Stdin)
	for {
		data, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("read from console failed, err:%v\n", err)
			break
		}

		data = strings.TrimSpace(data)

		_, err = conn.Write([]byte(data))
		if err != nil {
			fmt.Printf("write failed, err:%v\n", err)
			break
		}
	}
}

运行结果:

3.UDP通信

server.go

package main

import (
	"fmt"
	"net"
)

func main() {
	//建立一个UDP的监听,这里使用的是ListenUDP,并且地址是一个结构体
	listen, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   net.IPv4(0, 0, 0, 0),
		Port: 8080,
	})
	if err != nil {
		fmt.Printf("listen failed, err:%v\n", err)
		return
	}

	for {
		var data [1024]byte
		//读取UDP数据
		count, addr, err := listen.ReadFromUDP(data[:])
		if err != nil {
			fmt.Printf("read udp failed, err:%v\n", err)
			continue
		}

		fmt.Printf("recv data: %s addr: %v count: %d\n", string(data[0:count]), addr, count)
		//返回数据
		_, err = listen.WriteToUDP([]byte("hello client, I am UDP server ^_^ ^_^"), addr)
		if err != nil {
			fmt.Printf("write udp failed, err:%v\n", err)
			continue
		}
	}
}

client.go

package main

import (
	"fmt"
	"net"
)

func main() {
	// 创建连接
	socket, err := net.DialUDP("udp4", nil, &net.UDPAddr{
		IP:   net.IPv4(127, 0, 0, 1),
		Port: 8080,
	})
	if err != nil {
		fmt.Println("连接失败!", err)
		return
	}
	defer socket.Close()
	// 发送数据
	senddata := []byte("hello server, I am UDP client !")
	_, err = socket.Write(senddata)
	if err != nil {
		fmt.Println("发送数据失败!", err)
		return
	}
	// 接收数据
	data := make([]byte, 4096)
	read, remoteAddr, err := socket.ReadFromUDP(data)
	if err != nil {
		fmt.Println("读取数据失败!", err)
		return
	}
	fmt.Println(read, remoteAddr)
	fmt.Printf("%s\n", data)
}

运行结果:

4.TCP模拟HTTP协议通信

server.go

package main

import (
	"fmt"
	"net/http"
)

func main() {
	//http://127.0.0.1:8181/hello
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello world !"))
		fmt.Println("recv client connect ...")
	})

	server := http.Server{
		Addr:    "127.0.0.1:8181",
		Handler: nil, // 对应DefaultServeMux路由
	}
	server.ListenAndServe()
}

client.go

package main

import (
	"fmt"
	"io"
	"net"
)

func conn_baidu() {
	conn, err := net.Dial("tcp", "www.baidu.com:80")
	if err != nil {
		fmt.Printf("dial failed, err:%v\n", err)
		return
	}

	data := "GET / HTTP/1.1\r\n"
	data += "HOST: www.baidu.com\r\n"
	data += "connection: close\r\n"
	data += "\r\n\r\n"

	//写入数据
	_, err = io.WriteString(conn, data)
	if err != nil {
		fmt.Printf("wirte string failed, err:%v\n", err)
		return
	}

	var buf [1024]byte
	for {
		//读取返回的数据
		n, err := conn.Read(buf[:])
		if err != nil || n == 0 {
			break
		}

		fmt.Println(string(buf[:n]))
	}
}

func conn_myself() {
	conn, err := net.Dial("tcp", "127.0.0.1:8181")
	if err != nil {
		fmt.Printf("dial failed, err:%v\n", err)
		return
	}

	data := "GET /hello HTTP/1.1\r\n"
	data += "HOST: 127.0.0.1\r\n"
	data += "connection: close\r\n"
	data += "\r\n\r\n"

	//写入数据
	_, err = io.WriteString(conn, data)
	if err != nil {
		fmt.Printf("wirte string failed, err:%v\n", err)
		return
	}

	var buf [1024]byte
	for {
		//读取返回的数据
		n, err := conn.Read(buf[:])
		if err != nil || n == 0 {
			break
		}

		fmt.Println(string(buf[:n]))
	}
}

func main() {
	conn_myself()
}

运行结果:

5.利用TCP扫描那些端口被占用

port_scan.go

package main

import (
	"flag"
	"log"
	"net"
	"strconv"
	"strings"
	"sync"
	"time"
)

func processPortItem(port string) []string {
	var ports []string
	arr := strings.Split(port, ",")
	for _, p := range arr {
		if strings.Contains(p, "-") {
			ports = append(ports, rangeToArr(p)...)
		} else {
			ports = append(ports, p)
		}
	}
	return ports
}

func rangeToArr(s string) []string {
	if strings.Contains(s, "-") {
		var arr []string
		from, _ := strconv.Atoi(strings.Split(s, "-")[0])
		to, _ := strconv.Atoi(strings.Split(s, "-")[1])
		if from == 0 {
			from = 1
		}
		if to == 0 {
			to = 65535
		}
		for i := from; i <= to; i++ {
			arr = append(arr, strconv.Itoa(i))
		}
		return arr
	} else {
		return []string{s}
	}
}

func scan(ip string, port string, wg *sync.WaitGroup) {
	conn, err := net.DialTimeout("tcp", ip+":"+port, time.Second)
	if err != nil {
		wg.Done()
		return
	}
	wg.Done()
	defer conn.Close()
	log.Println(ip, port, "port use !")
}

func main() {
	ip := flag.String("h", "127.0.0.1", "scan IP")
	port := flag.String("p", "1-65536", "scan port")
	flag.Parse()
	log.Println("scan info is :", *ip, *port)

	//线程同步
	wg := &sync.WaitGroup{}

	for _, p := range processPortItem(*port) {
		wg.Add(1)
		go scan(*ip, p, wg)
	}
	wg.Wait()
}

运行结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/703251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【正点原子STM32连载】 第四十八章 内存管理实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第四…

全志V3S嵌入式驱动开发(spi-nand image制作)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 上一篇文章,我们说到了spi-nor image的制作和输入。相比较spi-nor,spi-nand虽然在稳定性上面差一点,但是价格上面有很大的优势。举例来说,一般32M的spi-nor大约在6-7元左右,但…

Springboot链接Redis实现AOP防止重复提交

目录 安装redis Springboot链接Redis 1.创建springboot项目 如果spring boot启动报Error creating bean with name redisUtil/redisTemplate 2.新建application.yml配置 3.redis配置类-直接用 4.redis工具类-直接用 5.写Controller测试 6.启动、测试 整合AOP&#xff…

内网横线移动—WmiSmbCrackMapExecProxyChainsImpacket

内网横线移动—Wmi&Smb&CrackMapExec&ProxyChains&Impacket 1. 前置环境准备2. wmic介绍2.1. wmic操作演示2.1.1. 受控主机上线2.1.1.1. 内网存活探测2.1.1.2. 密码抓取 2.1.2. 横向移动2.1.2.1. 上传文件2.1.2.2. 文件上传目标主机2.1.2.3. 执行木马 2.2. wmi…

JAVA 安全-JWT 安全及预编译 CASE 注入等(40)

在各种语言脚本的环境下&#xff0c;也会产生一些新的漏洞&#xff0c;如果是java又能产生那些漏洞&#xff0c;思维导图里面常规漏洞之前都有&#xff1b; java的访问控制&#xff0c;jwt令牌&#xff08;php几乎没有&#xff09;组件安全&#xff0c;这些都是java特有的 #综…

C#核心知识回顾——3.继承构造、拆装箱、多态

1.继承中的构造函数&#xff1a; 特点&#xff1a; 当申明一个子类对象时 先执行父类的构造函数&#xff0c;再执行子类的构造函数注意&#xff01;&#xff01;&#xff1a; 1.父类的无参构造很重要 2.子类可以通过base关键字代表父类调用父类构造 public class Mot…

【单片机】STM32单片机,定时器的输入捕获,基于捕获的频率计,STM32F103

文章目录 简单介绍外部计数频率计TIM5 频率计 简单介绍 下面的定时器都具有输入捕获能力&#xff1a; 外部计数频率计 查看另一篇文章&#xff1a;https://qq742971636.blog.csdn.net/article/details/131471539 外部计数频率计的缺点&#xff1a;需要两个定时器配合&#x…

控制 显示、隐藏

1、使用 v-if < v-if"isShow"></> data(){ return:{ isShow:false } } if (concepts && concepts.length >0){ this.isShow nv.concepts.includes(snap) } 确认 数组中有某个 字段&#xff0c;用includes 有&…

Qt QGraphics导入背景图并绘制图形,画布移动、缩放、图形旋转等

前言 之前写过一篇博文《Qt鼠标拖动绘制基本几何图形》 &#xff0c;这是介绍使用QGraphic中利用鼠标事件实现基本几何图形的绘制&#xff0c;支持直线、矩形、圆形、椭圆&#xff0c;本次是在此基础上进行扩展&#xff0c;实现背景图导入&#xff0c;并在图片上进行几何图形绘…

现货白银行情实时行情与展望

现货白银作为低门槛、高收益的贵金属投资工具&#xff0c;因为交易时间自且没有涨跌幅限制而大受全球投资者追捧&#xff0c;它每天的实时行情走势中充满机会&#xff0c;投资者可结合技术和基本面分析手段&#xff0c;预测其未来的价格走势&#xff0c;在市场的波动中把握住获…

Go编写流量代理工具

目录 这是一个演示主要分为俩包&#xff1a;流程&#xff1a;逻辑&#xff1a;(端口随意&#xff0c;本地ssh为例)用法&#xff1a;文件地址&#xff1a;代码如下&#xff1a; 这是一个演示 代理本地HTTP服务 代理局域网SSH服务 其他的TCP服务没测试了 主要分为俩包&#x…

什么是DevOps? 什么是DORA?

1. 前言 对于搞云原生应用的同学&#xff0c;对于DevOps和DORA应该都不陌生。但对于传统应用程序开发的同学&#xff0c;经常被DevOps, Microservice, CICD, DORA这些新颖的名词搞得晕头转向。那么到底什么是DevOps? 什么是DORA呢&#xff1f; 2. 解析 2.1 DevOps DevOps并…

群晖NAS搭建WebDV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址 转载自cpolar极点云文章&#xff1a;群晖NAS搭建WebDAV服务手机ES文件浏览器远程访问 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,我们在群辉中开启WebDav服…

支持刷机(OpenWrt)的路由器大全

2023年上半年最热门的刷机路由器当然是360T7、小米WR30U这两款&#xff0c;主要是性价比高&#xff0c;闲鱼100多搞定&#xff0c;支持刷OpenWrt、支持WiFi6&#xff0c;采用MTK798X系列处理器&#xff0c;性能强&#xff0c;轻松跑满千兆&#xff0c;如果你想追新&#xff0c;…

SpringMVC基础知识

一、SpringMVC 1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的&#xff0c;但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件…

云捷|打破应用孤岛加速企业数字化转型

CBG云服务BU X 神州数码云基地 一、引言 从流程信息化到整体的数字化转型&#xff0c;对企业而言是一场深刻的升级再造。企业在决心开启数字化转型之路后&#xff0c;有近5成民营企业数字化转型采用标准化工具&#xff1b;关于“贵公司未来将在工作中增加哪些数字应用的使用…

强化学习从基础到进阶-案例与实践[4.2]:深度Q网络DQN-Cart pole游戏展示

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

基于PaddleDetection fairmot目标跟踪 C++ 部署

1 源码下载 PaddleDetection 2 工程编译 参考&#xff1a;paddle 目标检测C部署流程 3 导出模型 python tools/export_model.py -c configs/mot/fairmot/fairmot_dla34_30e_576x320.yml --output_dir ./inference -o weightshttps://paddledet.bj.bcebos.com/models/mot/…

AutoSAR系列讲解(入门篇)4.7-BSW的Diagnostics功能

一、架构与术语解释 首先简单介绍以下诊断&#xff08;Diagnostics&#xff09;&#xff0c;由于百度百科中就有很好的解释&#xff0c;这里直接引用一下&#xff1a; 汽车诊断技术是凭借仪器设备对汽车进行性能测试和故障检查的方法和手段&#xff0c;它能够测试出汽车各项工作…

CMU 15-445 -- 存储篇 - 02

CMU 15-445 -- 存储篇 - 02 引言Database StorageDisk Manager 简介计算机存储体系为什么不使用 OS 自带的磁盘管理模块磁盘管理模块的核心问题在文件中表示数据库File StorageDatabase PagesHeap File OrganizationPage LayoutData LayoutTuple LayoutTuple Storage Data Repr…