2010-09-07 40 views
5
import socket 
backlog = 1 #Number of queues 

sk_1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sk_2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

local = {"port":1433} 
internet = {"port":9999} 

sk_1.bind (('', internet["port"])) 
sk_1.listen(backlog) 

sk_2.bind (('', local["port"])) 
sk_2.listen(backlog) 

Về cơ bản, tôi có mã này. Tôi đang cố gắng lắng nghe trên hai cổng: 1433 và 9999. Nhưng, điều này dường như không hoạt động.Python: Nghe trên hai cổng

Làm cách nào tôi có thể nghe trên hai cổng, trong cùng một tập lệnh python ??

Trả lời

4

Mã cho đến thời điểm này là tốt, theo như nó đi (ngoại trừ việc tồn đọng 1 có vẻ quá nghiêm ngặt), tất nhiên vấn đề xảy ra khi bạn cố gắng kết nối trên một cổng nghe, vì accept thường là chặn cuộc gọi (và "bỏ phiếu" bằng cách cố gắng chấp nhận với thời gian chờ ngắn trên một trong hai ổ cắm luân phiên sẽ ghi chu kỳ máy không có mục đích tốt).

select để giải cứu -!) select.select (hoặc trên các HĐH tốt hơn select.poll hoặc thậm chí select.epoll hoặc select.kqueue ... nhưng, tốt select.select công trình cũ ở khắp mọi nơi -!) Sẽ cho bạn biết các ổ cắm sẵn sàng và khi nào, vì vậy bạn có thể accept một cách thích hợp. Dọc theo các dòng này, asyncoreasynchat cung cấp thêm một tổ chức nữa (và khuôn khổ của bên thứ ba twisted, tất nhiên, thêm của chức năng "không đồng bộ" như vậy). Ngoài ra, bạn có thể dành các chủ đề riêng biệt để phục vụ hai ổ cắm nghe, nhưng trong trường hợp này, nếu các chức năng của ổ cắm khác nhau cần ảnh hưởng đến cùng cấu trúc dữ liệu được chia sẻ thì sự phối hợp (khóa & c) có thể trở nên dễ bị tắc nghẽn. Tôi chắc chắn sẽ khuyên bạn nên thử cách tiếp cận async đầu tiên - nó thực sự đơn giản hơn, cũng như cung cấp tiềm năng cho hiệu suất tốt hơn đáng kể! -)

+0

Nhưng, phần không hoạt động là hai liên kết. – mRt

+0

@mRt, bạn đang quan sát những triệu chứng nào với lệnh gọi 'bind'? Chúng dường như chính xác cho việc kết nối hai cổng trên tất cả các giao diện có sẵn (đó là những gì chuỗi rỗng "host" có nghĩa là, tất nhiên). –

10

Cách ưa thích-quần để làm điều này nếu bạn muốn sử dụng Python std-lib sẽ để sử dụng SocketServer với ThreadingMixin - mặc dù gợi ý 'chọn' có thể hiệu quả hơn. Mặc dù chúng tôi chỉ định nghĩa một ThreadedTCPRequestHandler nhưng bạn có thể dễ dàng sử dụng lại nó sao cho mỗi người nghe có một trình xử lý riêng độc đáo và nó khá tầm thường để bao bọc việc tạo máy chủ/thread thành một phương thức duy nhất nếu đó là thứ bạn thích .

#!/usr/bin/python 

import threading 
import time 
import SocketServer 

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): 

    def handle(self): 
     self.data = self.request.recv(1024).strip() 
     print "%s wrote: " % self.client_address[0] 
     print self.data 
     self.request.send(self.data.upper()) 

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    pass 

if __name__ == "__main__": 

    HOST = '' 
    PORT_A = 9999 
    PORT_B = 9876 

    server_A = ThreadedTCPServer((HOST, PORT_A), ThreadedTCPRequestHandler) 
    server_B = ThreadedTCPServer((HOST, PORT_B), ThreadedTCPRequestHandler) 

    server_A_thread = threading.Thread(target=server_A.serve_forever) 
    server_B_thread = threading.Thread(target=server_B.serve_forever) 

    server_A_thread.setDaemon(True) 
    server_B_thread.setDaemon(True) 

    server_A_thread.start() 
    server_B_thread.start() 

    while 1: 
     time.sleep(1) 
Các vấn đề liên quan