Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

python - Why is host aborting connection?

I'm teaching myself Python networking, and I recalled that back when I was teaching myself threading, I came across this page, so I copied the scripts, updated them for Python 3.1.1 and ran them. They worked perfectly.

Then I made a few modifications. My goal is to do something simple:

  1. The client pickles an integer and sends it to the server.
  2. The server receives the pickled integer, unpickles it, doubles it, then pickles it and sends it back to the client.
  3. The client receives the pickled (and doubled) integer, unpickles it, and outputs it.

Here's the server:

import pickle
import socket
import threading

class ClientThread(threading.Thread):
    def __init__(self, channel, details):
        self.channel = channel
        self.details = details
        threading.Thread.__init__ ( self )

    def run(self):
        print('Received connection:', self.details[0])
        request = self.channel.recv(1024)
        response = pickle.dumps(pickle.loads(request) * 2)
        self.channel.send(response)
        self.channel.close()
        print('Closed connection:', self.details [ 0 ])

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 2727))
server.listen(5)

while True:
    channel, details = server.accept()
    ClientThread(channel, details).start()

And here is the client:

import pickle
import socket
import threading

class ConnectionThread(threading.Thread):
    def run(self):
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect(('localhost', 2727))

        for x in range(10):
            client.send(pickle.dumps(x))
            print('Sent:',str(x))
            print('Received:',repr(pickle.loads(client.recv(1024))))

        client.close()

for x in range(5):
    ConnectionThread().start()

The server runs fine, and when I run the client it successfully connects and starts sending integers and receiving them back doubled as expected. However, very quickly it exceptions out:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:Python30libhreading.py", line 507, in _bootstrap_inner
    self.run()
  File "C:UsersImagistDesktopserverclient.py", line 13, in run
    print('Received:',repr(pickle.loads(client.recv(1024))))
socket.error: [Errno 10053] An established connection was aborted by the softwar
e in your host machine

The server continues to run and receives connections just fine; only the client crashes. What's causing this?

EDIT: I got the client working with the following code:

import pickle
import socket
import threading

class ConnectionThread(threading.Thread):
    def run(self):
        for x in range(10):
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client.connect(('localhost', 2727))
            client.send(pickle.dumps(x))
            print('Sent:',str(x))
            print('Received:',repr(pickle.loads(client.recv(1024))))
            client.close()

for x in range(5):
    ConnectionThread().start()

However, I still don't understand what's going on. Isn't this just opening and closing the socket a bunch of times? Shouldn't there be time limitations to that (you shouldn't be able to open a socket so soon after closing it)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your client is now correct - you want to open the socket send the data, receive the reply and then close the socket.

The error original error was caused by the server closing the socket after it sent the first response which caused the client to receive a connection closed message when it tried to send the second message on the same connection.

However, I still don't understand what's going on. Isn't this just opening and closing the socket a bunch of times?

Yes. This is acceptable, if not the highest performance way of doing things.

Shouldn't there be time limitations to that (you shouldn't be able to open a socket so soon after closing it)?

You can open a client socket as quickly as you like as every time you open a socket you will get a new local port number, meaning that the connections won't interfere. In the server code above, it will start a new thread for each incoming connection.

There are 4 parts to every IP connection (source_address, source_port, destination_address, destination_port) and this quad (as it is known) must change for ever connection. Everything except source_port is fixed for a client socket so that is what the OS changes for you.

Opening server sockets is more troublesome - if you want to open a new server socket quickly, your

server.bind(('', 2727))

Above then you need to read up on SO_REUSEADDR.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...