Basics of receiving files

This commit is contained in:
Justin Hawkins 2022-01-15 14:04:13 +10:30
parent 1e4ee09d5c
commit d90eab464d
4 changed files with 149 additions and 10 deletions

View File

@ -18,6 +18,7 @@ type Client struct {
address string address string
port int port int
list bool list bool
receive bool
} }
func (c *Client) Connect() error { func (c *Client) Connect() error {
@ -31,7 +32,7 @@ func (c *Client) Connect() error {
} }
defer conn.Close() defer conn.Close()
fmt.Printf("Connection on %s\n", address) log.Printf("Connection on %s\n", address)
sharedKey := secure.Handshake(conn) sharedKey := secure.Handshake(conn)
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}} secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}}
@ -67,6 +68,55 @@ func (c *Client) Connect() error {
conn.Close() conn.Close()
log.Printf("done listing") log.Printf("done listing")
} else if c.receive {
log.Printf("receiving a file")
// list mode
msg := secure.PacketStart{
OperationType: secure.OperationTypeReceive,
ClientName: "Justin Hawkins",
ProtocolVersion: "v1.0",
AuthToken: "abc123",
}
err := enc.Encode(msg)
if err != nil {
panic(err)
}
req := secure.PacketReceiveDataStartRequest{
Id: 234,
}
err = enc.Encode(req)
if err != nil {
panic(err)
}
// expect a response telling us if we can go ahead
res := secure.PacketReceiveDataStartResponse{}
err = dec.Decode(&res)
if err != nil {
panic(err)
}
log.Printf("server said %v", res)
if res.Status == secure.ReceiveDataStartResponseOK {
for {
res := secure.PacketReceiveDataNext{}
err = dec.Decode(&res)
if err != nil {
panic(err)
}
// log.Printf("got %d bytes, last is %t", res.Size, res.Last)
// print(res.Data)
os.Stdout.Write(res.Data[:res.Size])
if res.Last {
break
}
}
log.Printf("finished")
} else {
panic("don't handle this yet")
}
conn.Close()
} else { } else {
// must be send mode // must be send mode

View File

@ -8,20 +8,21 @@ import (
func main() { func main() {
log.SetFlags(log.Lshortfile) log.SetFlags(log.Lshortfile)
port := flag.Int("p", 9000, "Port to run server/client on.") port := flag.Int("port", 9000, "Port to run server/client on.")
addr := flag.String("a", "61.245.149.58", "address to connect to.") addr := flag.String("a", "61.245.149.58", "address to connect to.")
isServer := flag.Bool("s", false, "Set if running the server.") isServer := flag.Bool("s", false, "Set if running the server.")
isList := flag.Bool("l", false, "Set if requesting a list") isList := flag.Bool("l", false, "Set if requesting a list")
isReceive := flag.Bool("p", false, "Set if receiving a file")
flag.Parse() flag.Parse()
if *isServer { if *isServer {
fmt.Printf("Server running on %d\n", *port) log.Printf("Server running on %d\n", *port)
s := Server{port: *port} s := Server{port: *port}
s.Run() s.Run()
} else { } else {
fmt.Printf("Client running on %d\n", *port) log.Printf("Client running on %d\n", *port)
c := Client{port: *port, address: *addr, list: *isList} c := Client{port: *port, address: *addr, list: *isList, receive: *isReceive}
err := c.Connect() err := c.Connect()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)

View File

@ -178,6 +178,7 @@ type OperationTypeEnum byte
const ( const (
OperationTypeSend OperationTypeEnum = iota OperationTypeSend OperationTypeEnum = iota
OperationTypeList OperationTypeList
OperationTypeReceive
) )
// PacketStart is sent from the client to the server at the beginning // PacketStart is sent from the client to the server at the beginning
@ -193,6 +194,39 @@ type PacketSendDataStart struct {
Filename string Filename string
TotalSize uint32 TotalSize uint32
} }
type PacketSendDataNext struct {
Size uint16
Data []byte
}
// PacketReceiveDataStart is sent from the server to the client when
// the client asks for a file to be sent to them.
type PacketReceiveDataStartRequest struct {
Id uint32
}
type PacketReceiveDataStartResponseEnum byte
const (
// File transfer can begin
ReceiveDataStartResponseOK PacketReceiveDataStartResponseEnum = iota
// No such file by index
ReceiveDataStartResponseNotFound
)
// PacketReceiveDataStartResponse is the response to the above packet.
type PacketReceiveDataStartResponse struct {
Status PacketReceiveDataStartResponseEnum
Filename string
Kind string
TotalSize uint32
}
type PacketReceiveDataNext struct {
Size uint16
Data []byte
Last bool
}
type PacketListData struct { type PacketListData struct {
Id uint32 Id uint32
@ -200,8 +234,3 @@ type PacketListData struct {
FileSize uint32 FileSize uint32
Kind string Kind string
} }
type PacketSendDataNext struct {
Size uint16
Data []byte
}

View File

@ -147,6 +147,65 @@ func handleConnection(conn *net.TCPConn) {
log.Printf("done receiving file") log.Printf("done receiving file")
return return
} else if start.OperationType == secure.OperationTypeReceive {
log.Printf("client requesting file receive")
// wait for them to send the request
req := secure.PacketReceiveDataStartRequest{}
err := dec.Decode(&req)
if err != nil {
log.Printf("error expecting PacketReceiveDataStartRequest: %v", err)
return
}
log.Printf("The asked for %v", req)
res := secure.PacketReceiveDataStartResponse{
Status: secure.ReceiveDataStartResponseOK,
Filename: "abcdef",
Kind: "",
TotalSize: 12340,
}
err = enc.Encode(res)
if err != nil {
log.Printf("error sending PacketReceiveDataStartResponse: %v", err)
return
}
log.Printf("%#v", ngfs)
// now just start sending the file in batches
buf := make([]byte, 2048)
filename := ngfs[0].StorePath
log.Printf("opening %s", filename)
f, err := os.Open(filename)
for {
n, err := f.Read(buf)
eof := false
if err != nil && err != io.EOF {
log.Printf("error reading data: %v", err)
break
}
if err == io.EOF {
eof = true
}
chunk := secure.PacketReceiveDataNext{
Size: uint16(n),
Data: buf[:n],
Last: eof,
}
err = enc.Encode(chunk)
if err != nil {
log.Printf("error sending chunk: %v", err)
}
if eof {
break
}
}
log.Printf("sending done")
return
} else if start.OperationType == secure.OperationTypeList { } else if start.OperationType == secure.OperationTypeList {
log.Printf("client requesting file list") log.Printf("client requesting file list")