2011-02-24 44 views
5

Tôi đang gặp một chút rắc rối với ổ cắm trong Python. Bất cứ khi nào ai đó kết nối nó hoạt động tốt nhưng nếu họ ngắt kết nối chương trình máy chủ đóng lại. Tôi muốn chương trình máy chủ vẫn mở sau khi khách hàng đóng. Tôi đang sử dụng một vòng lặp True trong khi vẫn giữ kết nối còn sống nhưng khi máy khách đóng kết nối, máy chủ sẽ đóng kết nối của nó.Ổ cắm Python - giữ ổ cắm còn sống?

Đây là khách hàng:

import socket, sys 
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = sys.argv[1] 
port = int(sys.argv[2]) 
conn.connect((host, port)) 

print("Connected to host " + sys.argv[1]) 
td = 1 
while td == 1: 
    msg = raw_input('MSG: ') 

Đây là máy chủ:

import socket, sys 

socket.setdefaulttimeout(150) 
host = ''    
port = 50005 
socksize = 1024 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((host, port)) 
print("Server started on port: %s" % port) 
s.listen(1) 
print("Now listening...\n") 
conn, addr = s.accept() 

while True: 
    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 
+1

Bạn đang sử dụng n + 1 ổ cắm cho n kết nối? Bạn cần một ổ cắm đang lắng nghe mọi lúc. Ổ cắm nghe này chấp nhận các kết nối mới và mở ổ cắm khác mỗi lần kết nối được yêu cầu – Penang

+0

Bạn có thể đăng một đoạn mã ngắn để chứng minh sự cố không? – SimonJ

+0

n + 1 ổ cắm? Không chắc tôi có theo dõi không. Bạn có thể giải thích thêm một chút không? – AustinM

Trả lời

4

Nếu một khách hàng đóng một kết nối, bạn muốn nó để đóng socket.

Nó có vẻ như có một chút của một ngắt kết nối ở đây là tôi sẽ cố gắng xây dựng trên. Khi bạn tạo một ổ cắm, liên kết và lắng nghe, bạn đã thiết lập một cánh cửa mở cho những người khác đến và kết nối với bạn.

Khi khách hàng kết nối với bạn và bạn sử dụng cuộc gọi accept() để chấp nhận kết nối và nhận một ổ cắm mới (conn), được trả lại để bạn tương tác với ứng dụng khách. Ổ cắm nghe ban đầu của bạn vẫn ở đó và hoạt động, và bạn vẫn có thể sử dụng nó để chấp nhận nhiều kết nối mới hơn.

Nhìn vào mã của bạn, có thể bạn muốn làm một cái gì đó như thế này:

while True: 
    print("Now listening...\n") 
    conn, addr = s.accept() 

    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 

Xin lưu ý rằng đây chỉ là một điểm khởi đầu, và như những người khác đã gợi ý có thể bạn muốn sử dụng select() cùng với forking tắt quy trình hoặc các chủ đề sinh sản để phục vụ từng khách hàng.

+0

Cảm ơn điều này có vẻ là làm việc nhưng tôi nhận được một vấn đề khác. Nếu tôi tiếp tục gửi tin nhắn, khách hàng cuối cùng chỉ bị đóng băng. Không biết tại sao. – AustinM

+0

Bạn có thể mở rộng mã khách hàng của bạn và cách nó gửi dữ liệu không? – Jeff

2

Mã của bạn chỉ được chấp nhận một kết nối duy nhất - vòng lặp chỉ đề cập đến việc kết nối được chấp nhận đầu tiên và kết thúc càng sớm vì nó bị mất. Đây là cách máy chủ của bạn tồn tại:

data = conn.recv(socksize) 
if not data: 
    break 

Những gì bạn sẽ cần phải làm là chấp nhận một số kết nối, trong khi xử lý mỗi người trong vòng lặp riêng của nó. Lưu ý rằng nó không phải là một vòng lặp thực sự cho mỗi ổ cắm, bạn có thể sử dụng một cách tiếp cận dựa trên select để truy vấn mà các ổ cắm có một sự kiện liên kết với nó (dữ liệu có sẵn, kết nối bị mất vv) và sau đó quá trình chỉ những ổ cắm , tất cả trong cùng một vòng lặp.

Bạn cũng có thể sử dụng đa luồng quá trình tiếp cận/đa, đối phó với từng khách hàng trong quá trình thread riêng của nó hay - Tôi đoán bạn sẽ không chạy vào các vấn đề nhân rộng khi chơi xung quanh.

Xem:

http://docs.python.org/library/select.html

http://docs.python.org/library/multiprocessing.html

+1

Cảm ơn. Có thể bạn bởi bất kỳ cơ hội cho tôi một chút của một ví dụ về cách sử dụng chọn với ổ cắm? – AustinM

+0

@AustinM Tôi thứ hai này –