This could be a sign of network issues - ping doesn't catch all issues. The most likely culprit is a firewall or NAT device that is dropping the connection.
Adding -v for verbose output to scp will give you more detail as to what it's doing, and may give a better clue as to what is going on. If you want to post the output of a failed transfer with the -v option, I may be able to give a more exact answer.
Connection reset by peer means exactly that - the destination server reset/closed the connection. NAT devices will do this if there hasn't been any data sent for awhile, or if they are not working correctly.
Some ISPs will do this as a form of traffic shaping to limit peer to peer traffic - unfortunately some apply it to SSH connections as well. This likely won't be an issue on business connections, but if either end has a residential internet connection, it may apply.
The SSH server on windows could also be flaky. You don't specify which one you use, but not all of them work reliably.
In one real life example of weirdness, I had a friend who had similar issues - it turned out to be a bug in his cable modem's firmware that corrupted one out of every couple million packets. Rare enough that small transfers worked perfectly, but large ones would die every time.
Or it could just be normal internet issues. The internet is not 100% reliable, and never will be. Sometimes connections fail, sometimes packets get lost along the way. Sometimes the tiny men inside the ethernet cable go on strike and don't feel like carrying your packets. So you need a tool that can handle that, and keep retrying until it succeeds.
rsync would be a better choice here, simply because it allows resuming. This blog post explains how to setup rsync with resuming in place of scp. If necessary, you could write a simple shell script to check the exit code of rsync and keep retrying if it fails. This other blog post has an example of such a script.