2011-10-22 35 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

相关问题