Maybe I'm just dumb, but I always thought "broken pipe" meant, "the other end of this socket closed before I finished sending something" and "connection reset by peer" meant, well, roughly the same thing. (As well as indicating some slightly more esoteric problems.)
Turns out though, "broken pipe" actually means "I just tried to send something and the socket was already closed to sending."
So in the following example, if the other end of (TCP) socket "sock" closes or dies before the write method, "connection reset by peer" will be raised. The next write will give a broken-pipe error, since the socket now knows that further sending is invalid.
try: sock.write('foo') except: pass # connection reset by peer sock.write('bar') # broken pipe