简体   繁体   English

服务器/客户端脚本可在MacOSX上顺利运行,但在Ubuntu中将失败

[英]Server/client script runs smoothly on MacOSX but fails in Ubuntu

Me and my class mate are writing a server/client-model in Python for a school project. 我和我的同学正在用Python为学校项目编写服务器/客户端模型。 All the server script does is accepting connections made from clients (running on the localhost), and receives messages printing them to the terminal window. 服务器脚本所做的全部工作就是接受客户端(在本地主机上运行)建立的连接,并接收将其打印到终端窗口的消息。 The script was written on a Macbook Air running OSX10.7.3 64bit and acts as it should on this computer, but when run on my classmate's Linux computer (Ubuntu 11.04 64bit) or our computer lab Linux computer (Ubuntu 10.04 32bit) it runs somewhat different. 该脚本是在运行64位OSX10.7.3的Macbook Air上编写的,并且在此计算机上应有的作用,但是在我同学的Linux计算机(Ubuntu 11.04 64bit)或我们的计算机实验室Linux计算机(Ubuntu 10.04 32bit)上运行时,脚本运行有所不同。 In the script, both server and client are set to be non-blocking, and this works fine on my Mac as stated, but on the Linux-machine they acts as they were blocking, not allowing any data to be sent from Client nr2, before receiving any from Client nr1. 在脚本中,服务器和客户端均设置为非阻塞状态,如上所述,这在我的Mac上运行良好,但在Linux机器上,它们以阻塞状态运行,不允许从客户端nr2发送任何数据,在收到客户nr1的任何信息之前。

Shouldn't Python be a multiplatform language? Python不应该是一种多平台语言吗? And if not, what will be the best way to tweak our code, making it work as it should on both MacOS and Ubuntu? 如果不是,那么调整代码的最佳方法是什么,使其在MacOS和Ubuntu上都能正常工作?

I'm sorry if this was somewhat vague, but i post my code from both server and client script below. 很抱歉,如果这有点含糊,但是我从下面的服务器和客户端脚本中发布了我的代码。

Btw, my Mac runs Python 2.7.1, the Ubuntu 11.04 runs Python 2.7.1+, and the Ubuntu 10.04 runs Python 2.6.5. 顺便说一句,我的Mac运行Python 2.7.1,Ubuntu 11.04运行Python 2.7.1 +,Ubuntu 10.04运行Python 2.6.5。

As we are both new to socket programming and are beginners to Python (hence the school project and the simple code =)) it would be most appreciated if someone could please elaborate in a simple way. 由于我们既是套接字编程的新手,也是Python的初学者(因此是学校项目和简单的代码=),所以如果有人可以用简单的方式进行详细说明,将不胜感激。

First the server.py file: 首先是server.py文件:

import select
import socket
import sys
import threading
import client

class Server:
  def __init__(self):
    self.host = 'localhost'
    self.port = 50000
    self.backlog = 5
    self.size = 1024
    self.server = None
    self.threads = []

def openSocket(self):
    try: 
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind((self.host, self.port))
        self.server.listen(5)
        print "Listening to port " + str(self.port) + "..."
    except socket.error, (value,message):
        if self.server:
            self.server.close()
        print "Could not open socket: " + message
        sys.exit(1)

def run(self):
    self.openSocket()
    self.server.setblocking(0)
    input = [self.server,sys.stdin]
    running = True
    while running:

        inputready, outputready, exceptready = select.select(input,[],[], 0.01)             

        for s in inputready:
            c = client.Client(self.server.accept())
            self.threads.append(c)
            print "Client " + str(c.address) + " connected"
            inputready.pop()
        for c in self.threads:
            try:
                data = c.client.recv(self.size)
                print data
            except socket.error, (value,message):   
                continue

    #close threads
    self.server.close()
    for c in self.threads:
        c.join()

if __name__ == "__main__":
s = Server()
s.run()

Then the client.py file: 然后是client.py文件:

import select
import socket
import sys
import server
import threading

class Client(threading.Thread): 
def __init__(self,(client,address)): 
    threading.Thread.__init__(self) 
    self.client = client 
    self.address = address 
    self.size = 1024

def run(self):
    self.client.connect(('localhost',50000))
    c.client.setblocking(0)
    running = True 
    while running:

        line = sys.stdin.readline()
        if line == "exit":
            self.client.close()
        else:   
            self.client.sendall(line)

    self.client.close()

if __name__ == "__main__":
c = Client((socket.socket(socket.AF_INET, socket.SOCK_STREAM),'localhost'))
c.run()

PS: Nevermind the indentation on some loops. PS:不要在某些循环上缩进。 Something happened when i copy-pasted my code. 当我复制粘贴我的代码时发生了某些事情。 PPS: Note that we don't get any error messages when running this on either computer. PPS:请注意,在两台计算机上运行此命令时,我们都不会收到任何错误消息。 It just acts differently. 它的行为有所不同。

Thanks in advance 提前致谢

Admittedly, I have zero experience with non-blocking sockets, so I can't really help with that. 诚然,我对非阻塞套接字的使用经验为零,所以我对此无能为力。 However, the behaviour you described seems to be exactly what your code does - the server accepts a connection request, creates a new Client object, appends it to a list - and then listens to all the clients in that same list, one by one. 但是,您描述的行为似乎正是您的代码所执行的行为-服务器接受连接请求,创建一个新的Client对象,将其附加到列表中-然后逐一侦听同一列表中的所有客户端。 That means the first client is able to connect and send messages, but the next client can't connect because the server is receiving data from the first client. 这意味着第一个客户端能够连接和发送消息,但是下一个客户端无法连接,因为服务器正在从第一个客户端接收数据。

Also, this code is never reached: 另外,此代码永远不会到达:

    self.server.close()
    for c in self.threads:
        c.join()

because the server never stops accepting requests. 因为服务器永不停止接受请求。 What's more, you don't seem to start the threads, you're just creating them. 而且,您似乎并没有启动线程,而只是在创建它们。

Anyway, if you modify the server's run function like this, it should work: 无论如何,如果您这样修改服务器的运行功能,它应该可以工作:

from threading import Thread #this line is at the top of the file, of course

def run(self):
    self.openSocket()
    self.running = True #make sure to implement some code that'll actually set this variable to False!
    while self.running:
        c= client.Client(self.server.accept())
        t= Thread(target=self.listenToClient,args=[c])
        t.daemon= True #this makes sure to kill the thread when the main thread exits
        self.threads.append(t)
        t.start()

    #close threads
    self.server.close()
    for c in self.threads:
        c.join()

def listenToClient(self, c):
    print "Client " + str(c.address) + " connected"
    while self.running:
        try:
            data = c.client.recv(self.size)
            if data=='': #if the client disconnected
                return
            print data
        except socket.error, (value,message):   
            continue

Either I'm completely wrong or I have no clue why your code works on Mac OSX. 我完全错了,或者我不知道为什么您的代码可以在Mac OSX上运行。

PS: make sure not to use Python 3. That'd require some quirks. PS:请确保不要使用Python3。这需要一些怪癖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 脚本运行后在MacOsx上关闭Python进程 - Close Python Process on MacOsx after script runs Python 脚本在 pycharm 中运行但不在 ubuntu 终端中运行 - Python script runs in pycharm but not in ubuntu terminal Python pygame 客户端/服务器运行缓慢 - Python pygame Client/Server runs slow Windows中的Ubuntu子系统中的Python脚本失败-ModuleNotFoundError - Python script fails in Ubuntu subsystem in Windows - ModuleNotFoundError 在 ubuntu 服务器中运行多个脚本 - Run multiple script in ubuntu server selenium服务器,selenium客户端,在UBUNTU GUI服务器上 - selenium server, selenium client, on an UBUNTU GUI server 带有无头 Chrome 的 Tkinter 在 Mac 上运行良好,但在 Ubuntu 服务器上运行良好 - Tkinter with headless Chrome runs fine on Mac but not on Ubuntu server Python文件不在服务器上的Ubuntu上运行,但在Mac上本地运行 - Python file does not run on Ubuntu on server but runs in local on Mac Python 脚本在 PyCharm 中运行,但在任务计划程序 (Turbodbc) 中失败 - Python Script runs in PyCharm but Fails in Task Scheduler (Turbodbc) Shell中出现错误消息,但运行平稳 - Error message in shell but runs smoothly otherwise
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM