dongqu7778
dongqu7778
2015-12-03 18:03

在Windows上使用套接字

  • sockets
  • windows
  • posix

I'm currently working on a server/client project with go where I need to work with sockets without the net package. So I use POSIX functions I founded on syscall package. My server program in on Linux and my client in on Windows (8).

So basically, I want to connect the client to the server. The problem is when the client wants to Write in the socket it says "Fatal error : not supported by windows".

Client :

    package main

import (
    "fmt"
    "os"
    "runtime"
    s "syscall"
)

const (
    MAXSIZE = 500
    PORT    = 3000
)

var (
    ADDR = [4]byte{10, 8, 0, 1}
)

func Dial() (s.Handle, s.SockaddrInet4, error) {
    var sa s.SockaddrInet4 = s.SockaddrInet4{Port: PORT, Addr: ADDR}
    var d s.WSAData
    var sd s.Handle

    // a previous error told me to this
    if runtime.GOOS == "windows" {
        err := s.WSAStartup(uint32(0x202), &d)
        if err != nil {
            return sd, sa, err
        }
    }

    sd, err := s.Socket(s.AF_INET, s.SOCK_STREAM, 0)
    if err != nil {
        return sd, sa, err
    }

    s.Connect(sd, &sa)
    return sd, sa, err
}

func main() {
    sd, sa, err := Dial()
    check(err)
    defer s.Close(sd)

    _, err = s.Write(sd, make([]byte, 500,42))
    check(err)
}

func check(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

Server (works well) :

    package main

import (
    "fmt"
    "io/ioutil"
    "os"
    s "syscall"
)

const (
    PORT = 3000
)

func main() {
    var sa s.SockaddrInet4
    fmt.Println(sa)
    fd, err := s.Socket(s.AF_INET, s.SOCK_STREAM, 0)
    if err != nil {
        check(err)
    }
    defer s.Close(fd)
    if err := s.Bind(fd, &s.SockaddrInet4{Port: PORT, Addr: [4]byte{0, 0, 0, 0}}); err != nil {
        check(err)
    }

    if err := s.Listen(fd, 5); err != nil {
        check(err)
    }

    for {
        nfd, sa, err := s.Accept(fd)
        if err != nil {
            check(err)
        }

        go func(nfd int, sa s.Sockaddr) {
            var n int

            fmt.Println(sa)
            defer s.Close(nfd)

            b := make([]byte, 500)
            n, err = s.Read(nfd, b)
            check(err)
            fmt.Println(n)

        }(nfd, sa)
    }
}

func check(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

(Sry if my english is bad, I'm French)

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

1条回答