2012-07-20 16 views
14

Tôi đang cố viết chương trình truyền tệp bằng cách sử dụng ổ cắm. Máy chủ kết thúc mã đang chạy tốt. Tuy nhiên, ở phía khách hàng tôi nhận được lỗi sauPython socket.error: [Errno 111] Kết nối bị từ chối

Traceback (most recent call last): 
File "client.py", line 54, in <module> 
uploadFiles(directory) 
File "client.py", line 36, in uploadFiles 
transferFile(fname) 
File "client.py", line 13, in transferFile  
cs.connect((HOST, 36258)) 
File "/usr/lib/python2.7/socket.py", line 224, in meth 
return getattr(self._sock,name)(*args) 
socket.error: [Errno 111] Connection refused 

Mã của tôi là như sau

import os 
import socket 

def transferFile(fname): 
    HOST = '127.0.0.1' 
    CPORT = 36258 
    MPORT = 36250 
    FILE = fname 
    cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    cs.connect((HOST, 36258)) 
    cs.send("SEND " + FILE) 
    cs.close() 
    ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    ms.connect((HOST, MPORT)) 
    f = open(FILE, "rb") 
    data = f.read() 
    f.close() 
    ms.send(data) 
    ms.close() 

def uploadFiles(directory): 
    home = os.getenv("HOME") 
    folder = str(home + "/" + directory) 
    os.chdir(folder) 
    dirList = os.listdir(folder) 
    print dirList 
    for fname in dirList: 
     if fname.endswith('.bin'): 
      transferFile(fname) 

os.chdir(os.getenv("HOME")) 
directory = "testdownload" 
if not os.path.exists(directory): 
    os.makedirs(directory) 
os.chdir(directory) 

uploadFiles(directory) 

tôi đã cố gắng tìm kiếm sự giúp đỡ trên Google và các bài viết khác trên Stack Overflow, không ai trong số họ giúp đỡ. Ai đó có thể vui lòng giúp tôi? Số dòng có thể khác vì tôi chỉ dán một phần mã số

+0

Làm thế nào để bạn biết rằng máy chủ kết thúc đang làm việc? Thông báo lỗi cho thấy kết nối TCP tới 127.0.0.1:36258 đang bị từ chối. Điều gì sẽ xảy ra khi bạn chạy 'telnet 127.0.0.1 36258'? –

+0

Tôi chạy 'telnet 127.0.0.1 36258' và có thể thấy kết nối. 'Cố gắng 127.0.0.1 ... ' ' Kết nối với 127.0.0.1.' 'Escape nhân vật là '^]'.' Tôi đã kiểm tra cuối máy chủ và phát hiện ra rằng có một vấn đề với ổ cắm không mở lên đồng bộ với phía máy khách Cảm ơn – hld619

+0

Để thêm vào nhận xét ở trên, tôi đã thêm trễ 2 giây sau 'cs.close()' và sau 'ms.close()' để đồng bộ hóa với các kết nối trên máy chủ kết thúc và nó hoạt động như một sự quyến rũ. Cảm ơn tc – hld619

Trả lời

13

Vấn đề rõ ràng là (như bạn đã biết) cổng 36250 không mở ở phía máy chủ tại thời điểm bạn cố gắng kết nối (do đó kết nối bị từ chối). Tôi có thể thấy máy chủ được cho là mở ổ cắm này sau khi nhận được lệnh SEND trên một kết nối khác, nhưng dường như là "không mở [nó] đồng bộ với phía máy khách".

Vâng, lý do chính sẽ không có đồng bộ hóa nào. Gọi điện:

cs.send("SEND " + FILE) 
cs.close() 

sẽ chỉ đặt dữ liệu vào bộ đệm hệ điều hành; close có lẽ sẽ xóa dữ liệu và đẩy vào mạng, nhưng nó gần như chắc chắn sẽ trở lại trước khi dữ liệu đến được máy chủ. Thêm sleep sau close có thể giảm thiểu sự cố, nhưng đây không phải là đồng bộ hóa.

Giải pháp chính xác sẽ là đảm bảo máy chủ đã mở kết nối. Điều này sẽ yêu cầu máy chủ gửi lại cho bạn một số thông báo (ví dụ: OK hoặc tốt hơn PORT 36250 để cho biết nơi để kết nối). Điều này sẽ đảm bảo máy chủ đã lắng nghe.

Điều khác là bạn phải kiểm tra giá trị trả lại của send để đảm bảo số byte đã được lấy từ bộ đệm của bạn. Hoặc sử dụng sendall.

(Xin lỗi vì làm phiền với câu trả lời cuối này, nhưng tôi thấy đây là một câu hỏi giao thông cao và tôi thực sự không thích ý tưởng ngủ trong phần ý kiến.)

+0

Đã lâu rồi nhưng việc sử dụng giấc ngủ có vẻ ngớ ngẩn với tôi ngay bây giờ; anyways, cảm ơn bạn rất nhiều vì câu trả lời! :) – hld619