classification
Title: Python client failing to connect to server but completing as if successful
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: Seán Kelleher, iritkatriel, r.david.murray
Priority: normal Keywords:

Created on 2015-08-01 20:47 by Seán Kelleher, last changed 2020-11-30 23:13 by iritkatriel. This issue is now closed.

Messages (3)
msg247826 - (view) Author: Seán Kelleher (Seán Kelleher) Date: 2015-08-01 20:47
I have a Go server that listens to a port, runs a Python client to connect to the port as a subcommand, and reads from the client. However, the client (as follows) will occasionally run to completion without connecting to the port, but without raising an exception:

    import socket
    import sys

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    [addr, port] = sys.argv[1].split(':')
    sock.connect((addr, int(port)))
    try:
        sock.send("hello")
    finally:
        sock.close()

    print "done."

`server.go` follows:

	package main

	import (
		"log"
		"net"
		"os"
		"os/exec"
	)

	func main() {
		ln, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)})
		if err != nil {
			log.Fatalf("%v", err)
		}
		defer ln.Close()

		cmd := exec.Command(
			"python",
			"client.py",
			ln.Addr().(*net.TCPAddr).String(),
		)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr

		if err := cmd.Start(); err != nil {
			log.Fatalf("%v", err)
		}
		defer cmd.Process.Kill()

		go func() {
			log.Printf("command exited with: %v", cmd.Wait())
			log.Printf("closing listener: %v", ln.Close())
		}()

		conn, err := ln.Accept()
		if err != nil {
			log.Fatalf("%v", err)
		}

		buf := make([]byte, 1024)
		n, err := conn.Read(buf)
		log.Println(string(buf[:n]))
	}

When the connection is successful, the output is as expected:

    done.
    2015/08/01 21:03:50 hello

A failed connection, by contrast, gives no indication from Python that the command failed (`done.` is output), but it is evident that the connection was not established:

    done.
    2015/08/01 20:56:55 command exited with: <nil>
    2015/08/01 20:56:55 closing listener: <nil>
    2015/08/01 20:56:55 accept tcp4 127.0.0.1:42550: use of closed network connection
    exit status 1

From this, it appears as though the Python client thinks it has established a connection, because neither the `connect` nor the `send` call raise an exception.

This behaviour is corrected in Python 3 (all runs look like the first instance), so it appears to be local to Python 2.7.
msg247943 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-08-03 18:18
If whatever change fixed this has not already been backported to 2.7, it is likely that whatever it was was deemed to complex for backport.  If someone can figure out what the fix was and propose a reasonable way to back port it, we would most likely do so.
msg382209 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2020-11-30 23:13
Python 2 is past its EOL.
History
Date User Action Args
2020-11-30 23:13:13iritkatrielsetstatus: open -> closed

nosy: + iritkatriel
messages: + msg382209

resolution: out of date
stage: resolved
2015-08-03 18:18:48r.david.murraysetnosy: + r.david.murray
messages: + msg247943
2015-08-01 20:47:40Seán Kellehercreate