我正在尝试创建一个简单的 tcp 原始 winsock,但我的 socket.Recvfrom 出现错误“不支持的套接字”,我做错了什么?
package main
import (
"golang.org/x/sys/windows"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"log"
"net"
"sync"
"os"
//~ "syscall"
"time"
"fmt"
"errors"
"unsafe"
)
const SIO_RCVALL = windows.IOC_IN | windows.IOC_VENDOR | 1
type Handle struct {
blockForever bool
device string
deviceIndex int
mu sync.Mutex
socket windows.Handle
timeout time.Duration
snaplen int32
}
const BlockForever = -time.Millisecond * 10
func main() {
var (
device string = "eth0"
Snaplen int32 = 65536
Timeout time.Duration = 30 * time.Second
)
var (
ip4 layers.IPv4
tcp layers.TCP
)
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &ip4, &tcp)
decoded := []gopacket.LayerType{}
hnd, err := OpenLive(device, Snaplen, Timeout)
if err != nil {
log.Fatal(err)
}
defer hnd.Close()
packetSource := gopacket.NewPacketSource(hnd, hnd.LinkType())
for packetData := range packetSource.Packets() {
err := parser.DecodeLayers(packetData.Data(), &decoded)
if packetData == nil || err != nil {
continue
}
for _, layerType := range decoded {
switch layerType {
case layers.LayerTypeIPv4:
log.Println(" IP4 ", ip4.SrcIP, ip4.DstIP)
case layers.LayerTypeTCP:
log.Println(tcp.TransportFlow().Src().String())
}
}
}
}
func OpenLive(device string, snaplen int32, timeout time.Duration) (handle *Handle, err error) {
p := &Handle{}
p.blockForever = timeout < 0
p.timeout = timeout
p.snaplen = snaplen
var d windows.WSAData
log.Println("Initialising Winsock...")
err = windows.WSAStartup(uint32(0x202), &d)
if err != nil {
return nil, fmt.Errorf("Error: WSAStartup - %v", err)
}
log.Println("Initialised")
//Create a RAW Socket
log.Println("Creating RAW Socket...");
fd, err := windows.Socket(windows.AF_INET, windows.SOCK_RAW, windows.IPPROTO_IP)
if err != nil {
return nil, fmt.Errorf("Error: socket - %v", err)
}
p.socket = fd
log.Println("Created.")
// Retrieve the local hostname
hostname, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("Error: Hostname() - %v", err)
}
log.Printf("\nHost name : %s \n",hostname)
//Retrieve the available IPs of the local host
log.Println("Available Network Interfaces : \n")
_ , err = windows.GetHostByName(hostname)
if err != nil {
return nil, fmt.Errorf("Error: GetHostByName() - %v", err)
}
ip4 , iFcindex, err := externalIP()
if err != nil {
return nil, fmt.Errorf("Error: getIpv4() - %v", err)
}
p.deviceIndex = iFcindex
la := new(windows.SockaddrInet4)
la.Port = int(0)
for i := 0; i < net.IPv4len; i++ {
la.Addr[i] = ip4[i]
}
if err := windows.Bind(fd, la); err != nil {
return nil, fmt.Errorf ("Error:Bind - %v", err)
}
inbuf := uint32(1)
sizebuf := uint32(unsafe.Sizeof(inbuf))
ret := uint32(0)
err = windows.WSAIoctl(fd, SIO_RCVALL , (*byte)(unsafe.Pointer(&inbuf)) ,sizebuf, nil ,0 ,&ret , nil, 0);
if err != nil {
return nil, fmt.Errorf ("Error:WSAIoctl() failed - %v", err)
}
return p, nil
}
// Close closes the underlying socket handle.
func (p *Handle) Close() {
p.mu.Lock()
defer p.mu.Unlock()
windows.Close(p.socket)
}
func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
p.mu.Lock()
data = make([]byte, 65536)
n, _, err := windows.Recvfrom(p.socket, data, 0)
log.Println(n)
if err != nil {
log.Printf("Error:Recvfrom() - %v", err)
}
ci = gopacket.CaptureInfo{Timestamp: time.Now(), CaptureLength: len(data), Length: n, InterfaceIndex: p.deviceIndex}
p.mu.Unlock()
return
}
func htons(n int) int {
return int(int16(byte(n))<<8 | int16(byte(n>>8)))
}
func externalIP() (IPBYTE []byte, ifaceIndex int ,err error) {
ifaces, err := net.Interfaces()
if err != nil {
return
}
IPBYTE = make([]byte, 4)
ifaceIndex = 0
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
IPBYTE = ip.To4()
ifaceIndex = iface.Index
if IPBYTE == nil {
continue // not an ipv4 address
}
//~ err = nil
log.Printf("Active Network Interfaces %v : %v " ,iface.Index , ip.String())
return IPBYTE ,ifaceIndex , nil
}
}
err = errors.New("are you connected to the network?")
return
}
// LinkType returns pcap_datalink, as a layers.LinkType.
func (p *Handle) LinkType() layers.LinkType {
return layers.LinkTypeIPv4
}
最佳答案
在当前版本的Go中,错误信息是
not supported by windows
这是不言自明的。
如果您跟踪对 Recvfrom() 的调用,您会发现
func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
return 0, nil, syscall.EWINDOWS
}
也就是上面静态错误信息的返回。
关于windows - 转到 : Raw winsock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42475093/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解
我正在使用Maruku,将Markdown(超集)转换为HTML,你知道我该怎么做才能从HTML转换为Markdown吗? 最佳答案 Google发现了一个名为reverse_markdown的ruby脚本.它似乎可以满足您的需求。 关于ruby-on-rails-我需要从HTML转到markdown,有什么建议吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/175162
我在安装“redcarpet”gem时遇到以下错误。它在我friend的机器上安装没有问题。(我想安装它来运行yard)ruby版本:1.9.3命令输出:D:\Learning\Common_POM_FW\SampleProjects>yard[error]:Missing'redcarpet'gemforMarkdownformatting.Installitwith`geminstallredcarpet`D:\Learning\Common_POM_FW\SampleProjects>geminstallredcarpetTemporarilyenhancingPATHtoinc
我们正在开发一个需要推送通知的WP8应用程序。为了测试它,我们使用CURL命令行运行推送通知POST请求,确保它实际连接,使用客户端SSL证书进行身份验证并发送正确的数据。我们确实知道,当我们收到对设备的推送时,这项工作是有效的。这是我们一直用于测试目的的CURL命令:curl--certclient_cert.pem-v-H"Content-Type:text/xml"-H"X-WindowsPhone-Target:Toast"-H"X-NotificationClass:2"-XPOST-d"MytitleMysubtitle"https://db3.notify.live.ne
我在Windows7上运行Jekyll时遇到问题。当我运行时jekyll出现以下错误C:\temp\jekyll\kouphax.github.com>jekyllConfigurationfromC:/temp/jekyll/kouphax.github.com/_config.ymlBuildingsite:C:/temp/jekyll/kouphax.github.com->C:/temp/jekyll/kouphax.github.com/_siteunit-testingYouaremissingalibraryrequiredforTextile.Pleaserun:$[s
有没有办法使用vim结束Rubyblock?例如moduleSomeModule#defsome_methodendend我想用一个命令从光标所在的位置移动到block的末尾,这可能吗?我读过thisdocumentation,但它似乎不适用于.rb文件,我在某些地方读到它只适用于C(虽然还没有尝试过)。提前致谢。 最佳答案 rubyforge好像有官方包对此有一些支持:TheRubyftpluginnowincludesRubyspecificimplementationsforthe[[,]],[],][,[m,]m,[M,an