From 1aa968d93e22d3cfcd88f5c98c1de82ccae552b7 Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Mon, 6 Sep 2021 20:26:35 +0300 Subject: [PATCH] Added a handling for interrupt signal --- main.go | 2 ++ receiver/receiver.go | 29 ++++++++++++++++++++--------- sender/sender.go | 44 ++++++++++++++++++++++++++++---------------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/main.go b/main.go index fc3be26..1f62279 100644 --- a/main.go +++ b/main.go @@ -58,6 +58,7 @@ func main() { // 3) send info about the file -> 4) if accepted - upload file sender := sender.NewSender(*PORT, *SHAREDFILE) sender.WaitForConnection() + sender.HandleInterrupt() sender.MainLoop() } else { @@ -65,6 +66,7 @@ func main() { // 4) accept or refuse -> 5) download|don`t_download file receiver := receiver.NewReceiver(*DOWNLOADSFOLDER) receiver.Connect(fmt.Sprintf("%s:%d", *SENDERADDR, *PORT)) + receiver.HandleInterrupt() receiver.MainLoop() } } diff --git a/receiver/receiver.go b/receiver/receiver.go index 8396744..86285d6 100644 --- a/receiver/receiver.go +++ b/receiver/receiver.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "os" + "os/signal" "path/filepath" "strconv" "strings" @@ -21,9 +22,9 @@ type Receiver struct { IncomingPackets chan protocol.Packet FileToDownload *file EncryptionKey []byte - ReadyToReceive bool - Stopped bool TransferInfo *transferInfo + ReadyToReceive bool // waiting for a new packet + Stopped bool // controlls the mainloop } // Creates a new client with default fields @@ -58,19 +59,29 @@ func NewReceiver(downloadsFolder string) *Receiver { } } -// Closes the connection -func (r *Receiver) Disconnect() { - r.Connection.Close() +// When the interrupt signal is sent - exit cleanly +func (r *Receiver) HandleInterrupt() { + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt) + + go func() { + <-signalChan + r.Stop() + }() } // Closes the connection, warns the sender and exits the mainloop func (r *Receiver) Stop() { - disconnectionPacket := protocol.Packet{ - Header: protocol.HeaderDisconnecting, + if r.Connection != nil { + disconnectionPacket := protocol.Packet{ + Header: protocol.HeaderDisconnecting, + } + protocol.SendEncryptedPacket(r.Connection, disconnectionPacket, r.EncryptionKey) + r.Connection.Close() } - protocol.SendEncryptedPacket(r.Connection, disconnectionPacket, r.EncryptionKey) + r.Stopped = true - r.Disconnect() + } // Connects to a given address over tcp. Sets a connection to a corresponding field in receiver diff --git a/sender/sender.go b/sender/sender.go index 8144d52..2f9f1ca 100644 --- a/sender/sender.go +++ b/sender/sender.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "os" + "os/signal" "strconv" "time" @@ -21,9 +22,9 @@ type Sender struct { IncomingPackets chan protocol.Packet EncryptionKey []byte TransferInfo *transferInfo - TransferAllowed bool - ReceiverIsReady bool - Stopped bool + TransferAllowed bool // the receiver had agreed to receive a file + ReceiverIsReady bool // receiver is waiting for a new packet + Stopped bool // controlls the mainloop } // Creates a new sender with default|necessary fields @@ -41,8 +42,10 @@ func NewSender(port int, filepath string) *Sender { remoteIP, err := GetRemoteIP() if err != nil { - panic(err) + // don`t panic if couldn`t get remote IP + remoteIP = "" } + localIP, err := GetLocalIP() if err != nil { panic(err) @@ -70,23 +73,32 @@ func NewSender(port int, filepath string) *Sender { } } +// When the interrupt signal is sent - exit cleanly +func (s *Sender) HandleInterrupt() { + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt) + + go func() { + <-signalChan + s.Stop() + }() +} + // Closes the connection, warns about it the receiver and exits the mainloop func (s *Sender) Stop() { - disconnectionPacket := protocol.Packet{ - Header: protocol.HeaderDisconnecting, - } - err := protocol.SendEncryptedPacket(s.Connection, disconnectionPacket, s.EncryptionKey) - if err != nil { - panic(fmt.Sprintf("could not send a disconnection packet: %s", err)) + if s.Connection != nil { + disconnectionPacket := protocol.Packet{ + Header: protocol.HeaderDisconnecting, + } + err := protocol.SendEncryptedPacket(s.Connection, disconnectionPacket, s.EncryptionKey) + if err != nil { + panic(fmt.Sprintf("could not send a disconnection packet: %s", err)) + } + + s.Connection.Close() } s.Stopped = true - s.Disconnect() -} - -// Closes current connection -func (s *Sender) Disconnect() { - s.Connection.Close() } // Accepts one connection