2011-10-22 66 views
0

我正在嘗試使用一個online tutorial關於使用標準Python庫(版本2.7)的基本客戶端 - 服務器套接字編程的示例,但我無法得到該示例在Windows(Vista)下工作。它的工作原理在Ubuntu 11.10很好,所以我知道下面的代碼至少在基於UNIX的環境中工作:

在Windows中使用Python,如何通過套接字連接發送和檢索任意數量的數據?

import optparse, os, socket, time 

def parse_args(): 
    parser = optparse.OptionParser(usage) 

    help = "The port to listen on. Default to a random available port." 
    parser.add_option('--port', type='int', help=help) 

    help = "The interface to listen on. Default is localhost." 
    parser.add_option('--iface', help=help, default='localhost') 

    help = "The number of seconds between sending bytes." 
    parser.add_option('--delay', type='float', help=help, default=.1) 

    help = "The number of bytes to send at a time." 
    parser.add_option('--num-bytes', type='int', help=help, default=10) 

    options, args = parser.parse_args() 
    if len(args) != 1: 
     parser.error('Provide exactly one poetry file.') 
    poetry_file = args[0] 
    if not os.path.exists(args[0]): 
     parser.error('No such file: %s' % poetry_file) 
    return options, poetry_file 


def send_poetry(sock, poetry_file, num_bytes, delay): 
    inputf = open(poetry_file) 
    while True: 
     bytes = inputf.read(num_bytes) 
     if not bytes: 
      sock.close() 
      inputf.close() 
      return 

     print 'Sending %d bytes' % len(bytes) 

     try: 
      sock.sendall(bytes) # this is a blocking call 
     except socket.error: 
      sock.close() 
      inputf.close() 
      return 

     time.sleep(delay) 


def serve(listen_socket, poetry_file, num_bytes, delay): 
    while True: 
     sock, addr = listen_socket.accept() 
     print 'Somebody at %s wants poetry!' % (addr,) 
     send_poetry(sock, poetry_file, num_bytes, delay) 


def main(): 
    options, poetry_file = parse_args() 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    sock.bind((options.iface, options.port or 0)) 
    sock.listen(5) 
    print 'Serving %s on port %s.' % (poetry_file, sock.getsockname()[1]) 
    serve(sock, poetry_file, options.num_bytes, options.delay) 


if __name__ == '__main__': 
    main() 



程序停止只要插座在serve()調用accept()響應功能,並且沒有收到請求的數據,據我所知。我對Windows對套接字的處理有什麼看法?

+0

你怎麼知道的程序停止在「接受響應「?你看到「有人想要詩歌」的訊息嗎? –

+0

因爲我在永遠不會到達的聲明後面設置了一個斷點,所以不,我沒有看到「有人想要詩歌」的訊息 – clarkb86

+2

如果你遇到'接受'沒有人連接到您的套接字,請嘗試telnet連接到端口,下面的答案也有很好的信息 –

回答

3

它看起來像你可能需要讓它運行在2個不同的進程或將客戶端和服務器分成2個不同的線程。我得到這個在我的Win7箱的工作只是現在:

client.py

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect(("localhost", 4242)) 
while True: 
    line = input("String to send: ") 
    s.send(line.encode("utf-8")) 

server.py:

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(("0.0.0.0", 0)) 
s.listen(5) 
client, address = s.accept() 
while 1: 
    data = client.recv(1024) 
    if data: 
     client.send(data) 
     print(data.decode("utf-8")) 

結果:

C:\用戶\ jon \ Desktop> python.exe client.py
要發送的字符串:「Hello!」

單獨的控制檯

C:\用戶\喬恩\桌面>蟒蛇server.py
您好!在Winsock Programmer’s FAQ


腳本

更多好消息您使用掛起在sock, addr = listen_socket.accept()(如果之前已設置與sock.settimeout(x)到達超時)。如果使用sock.setblocking(0),異常socket.error: [Errno 10035] A non-blocking socket operation could not be completed immediately是在accept()線拋出,這是一個超時會發生什麼:

def serve(listen_socket, poetry_file, num_bytes, delay): 
    while True: 
     print "accepting data" 
     try: 
      sock, addr = listen_socket.accept() 
     except socket.error, e: 
      print e 
     else: 
      print 'Somebody at %s wants poetry!' % (addr,) 
      send_poetry(sock, poetry_file, num_bytes, delay) 


def main(): 
    options, poetry_file = parse_args() 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind((options.iface, options.port or 0)) 
    sock.listen(5) 
    sock.settimeout(5) 
    print 'Serving %s on port %s.' % (poetry_file, sock.getsockname()[1]) 
    serve(sock, poetry_file, options.num_bytes, options.delay) 


if __name__ == '__main__': 
    main() 

結果:

C:\Users\jon\Desktop>python.exe test.py poetry.txt            
Serving poetry.txt on port 25355.                 
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data                      
timed out                       
accepting data 
+0

首先,謝謝因爲經歷了爲我測試所有的麻煩。不過,我真的很想知道爲什麼我的代碼在Windows中不起作用,因爲我認爲它涉及到重要的事情,可能會再次出現。經過一些更多的研究後,我認爲這個問題與我正在使用的'SO_REUSEADDR'選項有關。這個選項[應該]允許客戶端和服務器在localhost接口上運行,沒有任何問題,但事實並非如此。 – clarkb86

+0

理論上,這是正確的。但是從我讀過的和運行一些測試之後,它似乎有時會起作用,但不是其他測試。我也讀過,重新啓動你的電腦實際上可以使它工作一段時間,但最終它會無限期地掛起來,就像它在我們的測試中一樣。更多好信息在這裏:http://itamarst.org/writings/win32sockets.html – chown

+0

嘿,我今天發現這篇文章。這個人基本上說(在看起來是廣泛的研究之後),Windows中出現了奇怪的,不一致的事情,這就是它的方式(也許是這樣)。 – clarkb86

相關問題