Tôi tự dạy mình mạng Python, và tôi nhớ lại khi tôi đang dạy bản thân mình, tôi bắt gặp this page, vì vậy tôi đã sao chép các tập lệnh, cập nhật chúng cho Python 3.1.1 và chạy chúng. Họ làm việc hoàn hảo.Tại sao máy chủ lưu trữ hủy kết nối?
Sau đó, tôi đã thực hiện một vài sửa đổi. Mục tiêu của tôi là làm điều gì đó đơn giản:
- Khách hàng chọn một số nguyên và gửi đến máy chủ.
- Máy chủ nhận số nguyên đã chọn, giải nén nó, tăng gấp đôi, sau đó chọn và gửi lại cho khách hàng.
- Khách hàng nhận được số nguyên đã được ngâm (và tăng gấp đôi), giải mã nó và xuất kết quả.
Đây là máy chủ:
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()
Và đây là các khách hàng:
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()
Các máy chủ chạy tốt, và khi tôi chạy client nó kết nối thành công và bắt đầu gửi các số nguyên và nhận chúng trở lại gấp đôi như mong đợi. Tuy nhiên, rất nhanh chóng ngoại lệ:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python30\lib\threading.py", line 507, in _bootstrap_inner
self.run()
File "C:\Users\Imagist\Desktop\server\client.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
Máy chủ tiếp tục chạy và nhận kết nối tốt; chỉ có khách hàng bị treo. Điều gì gây ra điều này?
EDIT: Tôi đã nhận khách hàng làm việc với đoạn mã sau:
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()
Tuy nhiên, tôi vẫn không hiểu những gì đang xảy ra. Đây không phải là chỉ mở và đóng socket một loạt các lần? Không nên có giới hạn thời gian cho điều đó (bạn không nên mở một ổ cắm ngay sau khi đóng nó)?
Có một số lỗi rõ ràng trong các mã, có vẻ như giả định 1 gửi cuộc gọi trên một kết quả bên trong 1 cuộc gọi recv ở phía bên kia, mà có thể không đúng, TCP là một giao thức stream, nó không phải là thông điệp hoặc gói theo định hướng. Tuy nhiên, không chắc chắn cách liên quan đến thông báo lỗi. – leeeroy
@leeroy Tôi rõ ràng là loại mới này, vì vậy tôi hoàn toàn mở cửa cho những lời chỉ trích ở đây. Bạn dường như được gợi ý rằng tôi không nên sử dụng TCP vì nó là dòng chứ không phải là gói theo định hướng; nhưng không thể đại diện cho một gói chỉ đơn giản là một luồng dữ liệu rất ngắn? Tôi biết nó không phải là nó * nên * được sử dụng nhưng đây chỉ là để thử nghiệm ra; rõ ràng là tôi có ý định đẩy nhiều dữ liệu hơn một số nguyên duy nhất. – Imagist
@leeroy (tiếp theo) Mục tiêu của tôi là làm việc để thực hiện một cái gì đó như thế này: http://www.mcwalter.org/technology/java/httpd/tiny/index.html chỉ bằng Python. – Imagist