Created
May 11, 2014 23:05
-
-
Save DivinityArcane/20da197592c6e35943df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package network | |
import ( | |
"net" | |
"io" | |
"time" | |
"bufio" | |
) | |
// It's simpler to use a bufio.Reader, instead of dealing with | |
// split packets ourselves, since bufio.Reader will stop at | |
// null-characters (which dAmn uses to mark the end of the payload) | |
// This does not apply to the Writer, however, as bufio.Writer | |
// will not correctly send the null-character as far as I have | |
// tested, and there-for breaks all out-bound packets. This | |
// is because bufio sees a null-character as EOF. | |
type Socket struct { | |
Handle net.Conn | |
Reader *bufio.Reader | |
PacketQueue chan *Packet | |
Address string | |
Open bool | |
} | |
// An override, that follows the "New<T>" naming convention. | |
func NewSocket(address string) (Socket, error) { | |
d := Socket{} | |
e := d.Connect(address) | |
return d, e | |
} | |
func (d *Socket) Connect(address string) error { | |
sock, err := net.DialTimeout("tcp", address, time.Second * 5) | |
if err != nil { | |
return err | |
} | |
d.Address = address | |
d.Handle = sock | |
d.Reader = bufio.NewReader(sock) | |
d.PacketQueue = make(chan *Packet) | |
// raise connect event? | |
d.Open = true | |
go d.ReceiveLoop() | |
return nil | |
} | |
func (d *Socket) Send(p Packet) (int, error) { | |
if !d.Open { | |
return -1, io.EOF | |
} | |
return d.Handle.Write([]byte(p.String() + "\x00")) | |
} | |
func (d *Socket) Receive() (int, Packet, error) { | |
if !d.Open { | |
return -1, Packet{}, io.EOF | |
} | |
s, e := d.Reader.ReadString(0) | |
if e != nil { | |
return -1, Packet{}, e | |
} | |
if len(s) <= 0 { | |
return -1, Packet{}, io.EOF | |
} | |
p := ParsePacket(s[:len(s)-1]) | |
return len(s), p, nil | |
} | |
func (d *Socket) ReceiveLoop() { | |
n, p, e := d.Receive() | |
if e != nil || n == -1 { | |
d.Open = false | |
return | |
} | |
d.PacketQueue<- &p | |
d.ReceiveLoop() | |
} | |
func (d *Socket) Disconnect() { | |
d.Handle.Close() | |
d.Open = false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment