tcp 经典应用

This commit is contained in:
impact-eintr
2021-08-09 20:54:57 +08:00
parent 843f2fe80a
commit 769040cb81
3 changed files with 91 additions and 0 deletions

38
example/tcp_server.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"fmt"
"log"
"net"
"runtime"
"strings"
)
type TCPHandler interface {
Handle(net.Conn)
}
func TCPServer(listener net.Listener, handler TCPHandler, logf lg.AppLogFunc) error {
log.Printf("TCP: listening on %s", listener.Addr())
for {
clientConn, err := listener.Accept()
if err != nil {
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
log.Printf("temporary Accept() failure - %s", err)
runtime.Gosched()
continue
}
// theres no direct way to detect this error because it is not exposed
if !strings.Contains(err.Error(), "use of closed network connection") {
return fmt.Errorf("listener.Accept() error - %s", err)
}
break
}
go handler.Handle(clientConn)
}
log.Printf("TCP: closing %s", listener.Addr())
return nil
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

View File

@@ -2,7 +2,10 @@ package tuntap
import ( import (
"errors" "errors"
"fmt"
"os/exec"
"syscall" "syscall"
"unsafe"
) )
const ( const (
@@ -44,6 +47,38 @@ func NewNetDev(c *Config) (fd int, err error) {
} }
// SetLinkUp 让系统启动该网卡
func SetLinkUp(name string) (err error) {
out, cmdErr := exec.Command("ip", "link", "set", name, "up").CombinedOutput()
if cmdErr != nil {
err = fmt.Errorf("%v:%v", cmdErr, string(out))
return
}
return
}
// SetRoute 通过ip命令添加路由
func SetRoute(name, cidr string) (err error) {
out, cmdErr := exec.Command("ip", "link", "set", name, "up").CombinedOutput()
if cmdErr != nil {
err = fmt.Errorf("%v:%v", cmdErr, string(out))
return
}
return
}
// SetRoute 通过ip命令添加IP地址
func AddIP(name, ip string) (err error) {
out, cmdErr := exec.Command("ip", "link", "set", name, "up").CombinedOutput()
if cmdErr != nil {
err = fmt.Errorf("%v:%v", cmdErr, string(out))
return
}
return
}
func newTun(name string) (int, error) { func newTun(name string) (int, error) {
return open(name, syscall.IFF_TUN|syscall.IFF_NO_PI) return open(name, syscall.IFF_TUN|syscall.IFF_NO_PI)
@@ -56,9 +91,27 @@ func newTAP(name string) (int, error) {
// 先打开一个字符串设备通过系统调用将虚拟网卡和字符串设备fd bind在一起 // 先打开一个字符串设备通过系统调用将虚拟网卡和字符串设备fd bind在一起
func open(name string, flags uint16) (int, error) { func open(name string, flags uint16) (int, error) {
// 打开一个字符串设备 得到自负设备的文件描述符
fd, err := syscall.Open("/dev/net/tun", syscall.O_RDWR, 0) fd, err := syscall.Open("/dev/net/tun", syscall.O_RDWR, 0)
if err != nil { if err != nil {
return -1, err return -1, err
} }
var ifr struct {
name []byte
flags uint16
_ [22]byte
}
copy(ifr.name[:], name)
ifr.flags = flags
// 通过ioctl系统调用 将fd和虚拟网卡驱动绑定在一起
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd),
syscall.TUNSETIFF, uintptr(unsafe.Pointer(&ifr)))
if errno != 0 {
syscall.Close(fd)
return -1, errno
}
return fd, nil
} }