On Wed, Mar 6, 2019 at 9:21 AM Tom Lane <t...@sss.pgh.pa.us> wrote:
> The bug #15598 report is more troublesome, as we don't have a strong
> reason to believe it's not common on Windows.  However, I wonder whether
> we can really do anything at all about that one.  If I understand what
> Andrew was hypothesizing in that thread, it was that Windows might be
> dropping undelivered data on the floor once the server closes its end
> of the connection.  That would be totally broken behavior, but I never
> expect anything else from Microsoft :-(.  If that is an accurate theory
> then rewriting libpq won't fix it.

Here is a stupid Python 2.7 program to try to test that.  Run one copy
of it like this:

$ python ./test.py --server

The server will wait for a client, send a message immediately, and
then close the socket after a second.  The client will connect and
send something once before and twice after the server closes the
socket, and finally see if it can read the message from the server.

Here's the output I get from the client on some different systems (the
server was running on the same system):

$ uname -a
Linux debian 4.18.0-3-amd64 #1 SMP Debian 4.18.20-2 (2018-11-23)
x86_64 GNU/Linux
$ python ./test.py --client
Sending A...
2
Sending B...
[Errno 104] Connection reset by peer
Sending C...
[Errno 32] Broken pipe
This is the server saying goodbye

$ uname -a
Darwin macaque.local 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20
20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
$ python2.7 ./test.py --client
Sending A...
2
Sending B...
[Errno 32] Broken pipe
Sending C...
[Errno 32] Broken pipe
This is the server saying goodbye

$ uname -a
FreeBSD dogmatix 13.0-CURRENT FreeBSD 13.0-CURRENT c0873ea614a(master)
GENERIC  amd64
$ python2.7 ./test.py --client
Sending A...
2
Sending B...
2
Sending C...
2
This is the server saying goodbye

So... can anyone tell us what happens on Windows?

(A secondary question might be what happens if the server and client
are on different machines since I guess it could be different?)

-- 
Thomas Munro
https://enterprisedb.com
import socket
import sys
import time

address = ("localhost", 8888)

def server():
  ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  ss.bind(address)
  ss.listen(5)
  (s, other_address) = ss.accept()
  # Send a message, but then close the socket shortly after.
  # Will the client manage to read the goodbye message, if it tries to write
  # first?
  s.send("This is the server saying goodbye\n")
  time.sleep(1)
  s.close()

def client():
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect(address)
  # Try to send a message immediately.  At this point we expect the server
  # end to be waiting for a second before closing, so it should be OK.
  try:
    print "Sending A..."
    sent = s.send("A\n")
    print sent
  except Exception, e:
    # (Should not be reached)
    print e
  # Wait until after the server has closed its socket, and try to send
  # another message.
  time.sleep(2)
  try:
    print "Sending B..."
    sent = s.send("B\n")
    print sent
  except Exception, e:
    # We expect an error either here or at the next write (?)
    print e
  # Send one more message, just to see if perhaps an error will be reported
  # here rather than earlier...
  try:
    print "Sending C..."
    sent = s.send("C\n")
    print sent
  except Exception, e:
    # What about now?
    print e
  # Can we read the goodbye message?
  print s.recv(1024)

if __name__ == "__main__":
  if sys.argv[1] == "--server":
    server()
  elif sys.argv[1] == "--client":
    client()

Reply via email to