Go语言linux下构造tcp数据包(不使用net包和Cgo)
来源:互联网 发布:有淘宝账号就能贷款 编辑:程序博客网 时间:2024/05/16 04:02
Golang可以通过syscall包中的相关socket函数(Windows和Linux中syscall中网络编程的函数不太一样)来进行网络编
程,可以用我们熟悉的方法使用raw socket,因为最近在搞一些协议的学习,所以特意试了试,和普通的linux+C的
socket编程基本没什么区别。
代码如下:
package mainimport ( "bytes" "encoding/binary" . "fmt" "strconv" "strings" "syscall" "unsafe")type TCPHeader struct { SrcPort uint16 DstPort uint16 SeqNum uint32 AckNum uint32 Offset uint8 Flag uint8 Window uint16 Checksum uint16 UrgentPtr uint16}type PsdHeader struct { SrcAddr uint32 DstAddr uint32 Zero uint8 ProtoType uint8 TcpLength uint16}func inet_addr(ipaddr string) uint32 { var ( segments []string = strings.Split(ipaddr, ".") ip [4]uint64 ret uint64 ) for i := 0; i < 4; i++ { ip[i], _ = strconv.ParseUint(segments[i], 10, 64) } ret = ip[3]<<24 + ip[2]<<16 + ip[1]<<8 + ip[0] return uint32(ret)}func htons(port uint16) uint16 { var ( high uint16 = port >> 8 ret uint16 = port<<8 + high ) return ret}func CheckSum(data []byte) uint16 {var (sum uint32length int = len(data)index int)for length > 1 {sum += uint32(data[index])<<8 + uint32(data[index+1])index += 2length -= 2}if length > 0 {sum += uint32(data[index])}sum += (sum >> 16)return uint16(^sum)}func main() { var ( msg string psdheader PsdHeader tcpheader TCPHeader ) Printf("Input the content: ") Scanf("%s", &msg) /*填充TCP伪首部*/ psdheader.SrcAddr = inet_addr("127.0.0.1") psdheader.DstAddr = inet_addr("127.0.0.1") psdheader.Zero = 0 psdheader.ProtoType = syscall.IPPROTO_TCP psdheader.TcpLength = uint16(unsafe.Sizeof(TCPHeader{})) + uint16(len(msg)) /*填充TCP首部*/ tcpheader.SrcPort = htons(3000) tcpheader.DstPort = htons(8080) tcpheader.SeqNum = 0 tcpheader.AckNum = 0 tcpheader.Offset = uint8(uint16(unsafe.Sizeof(TCPHeader{}))/4) << 4 tcpheader.Flag = 2 //SYN tcpheader.Window = 60000 tcpheader.Checksum = 0 /*buffer用来写入两种首部来求得校验和*/ var ( buffer bytes.Buffer ) binary.Write(&buffer, binary.BigEndian, psdheader) binary.Write(&buffer, binary.BigEndian, tcpheader) tcpheader.Checksum = CheckSum(buffer.Bytes()) /*接下来清空buffer,填充实际要发送的部分*/ buffer.Reset() binary.Write(&buffer, binary.BigEndian, tcpheader) binary.Write(&buffer, binary.BigEndian, msg) /*下面的操作都是raw socket操作,大家都看得懂*/ var ( sockfd int addr syscall.SockaddrInet4 err error ) if sockfd, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_TCP); err != nil { Println("Socket() error: ", err.Error()) return } defer syscall.Shutdown(sockfd, syscall.SHUT_RDWR) addr.Addr[0], addr.Addr[1], addr.Addr[2], addr.Addr[3] = 127, 0, 0, 1 addr.Port = 8080 if err = syscall.Sendto(sockfd, buffer.Bytes(), 0, &addr); err != nil { Println("Sendto() error: ", err.Error()) return } Println("Send success!")}
如果转载请注明文章出处:http://blog.csdn.net/gophers/article/details/20393601
0 0
- Go语言linux下构造tcp数据包(不使用net包和Cgo)
- Golang在windows下的socket编程(不使用net包和Cgo)
- Linux下GO语言内存共享,CGO实现
- Go语言 使用CGo进行优化
- 在Go包里添加C代码并且不使用CGO(不需要gcc)
- Go语言使用CGO获取Windows的CPU使用率
- go语言cgo -- C与Go互调
- C语言?Go语言?还是CGO语言!
- go语言(使用了cgo与硬件交互),算上空行和注释共200行代码
- go语言的cgo简单教程
- go语言的cgo简单教程
- go cgo
- go--cgo
- Go语言备忘录:net/http包的使用模式和源码解析
- TCP数据包的封包和拆包
- golang go语言与C语言互调,通过cgo
- go 语言 net 扩展 模拟 tcp 收发
- GO语言linux下环境变量
- 作业、进程、线程
- LeetCode Restore IP Addresses
- poj 3225 线段树 经典题
- [转]nosql数据库学习一:安装和使用memcached
- mysql安装
- Go语言linux下构造tcp数据包(不使用net包和Cgo)
- 构造螺旋矩阵
- Linux用户组添加查看
- Ubuntu13.04 “Language support” icon missing in System Settings
- 最大子段和
- 每天一个linux命令(47):iostat命令
- 数据建模基础理论 – 数据建模及规范化(1)
- XManager4基于gdm连接centos6.4图形界面(绝对可用)
- 控件使用