Я и мой одноклассник пишем модель сервера / клиента на Python для школьного проекта. Все, что делает серверный скрипт - принимает соединения, сделанные от клиентов (запущенных на локальном хосте), и получает сообщения, распечатывая их в окне терминала. Сценарий был написан на Macbook Air, работающем под управлением OSX10.7.3 64bit, и работает так, как должен на этом компьютере, но при запуске на компьютере моего одноклассника Linux (Ubuntu 11.04 64bit) или на нашем компьютере под управлением Linux (Ubuntu 10.04 32bit) он работает несколько иначе , В сценарии и сервер, и клиент настроены как неблокирующие, и, как указано, на моем Mac это работает нормально, но на Linux-машине они действуют так же, как и на блокировке, не позволяя отправлять какие-либо данные с клиента nr2, до получения любого от клиента № 1.
Разве Python не должен быть мультиплатформенным языком? И если нет, то как лучше всего настроить наш код, чтобы он работал как на MacOS, так и на Ubuntu?
Извините, если это было несколько расплывчато, но я публикую свой код из сценария сервера и клиента ниже.
Кстати, мой Mac работает на Python 2.7.1, Ubuntu 11.04 работает на Python 2.7.1+, а Ubuntu 10.04 работает на Python 2.6.5.
Поскольку мы оба новички в программировании сокетов и являемся новичками в Python (отсюда и школьный проект, и простой код =)), было бы очень признательно, если бы кто-то мог объяснить это простым способом.
Сначала файл 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()
Затем файл 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: не обращайте внимания на отступы в некоторых циклах. Что-то случилось, когда я скопировал свой код.
PPS: Обратите внимание, что мы не получаем никаких сообщений об ошибках при запуске этого на любом компьютере. Это просто действует по-другому.
Заранее спасибо