Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Network
  • » Создание сервера с неограниченым числом подключений [RSS Feed]

#1 Авг. 26, 2010 22:34:17

CryptSpirit
От:
Зарегистрирован: 2010-05-05
Сообщения: 88
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Вот написал пример в котором ждет себе программа когда кто то к сокету конектится. Еслиесть конект то милости просим в отдельный поток. Проблема по сабжу что потоков явно для неорганиченого числа подключений не хватает. Вопрос что делать? Давать на трэд по несколько конектов обслуживать? Заранее спасиб.



Отредактировано (Авг. 26, 2010 22:38:57)

Офлайн

#2 Авг. 27, 2010 00:23:54

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Насчет неограниченного числа подключений вы явно погорячились, но используя треды, а если их будет мало, то gevent, это число можно серьезно увеличить.

Читать здесь:
http://docs.python.org/library/asyncore.html
http://docs.python.org/library/socketserver.html?highlight=tcp%20server
http://www.gevent.org/intro.html



Офлайн

#3 Авг. 27, 2010 00:34:43

CryptSpirit
От:
Зарегистрирован: 2010-05-05
Сообщения: 88
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Потоки как мне кажется это реальный выход. Но это попахивает идиотизмом создавать такое количество потоков. Будем копать.



Офлайн

#4 Авг. 27, 2010 00:56:07

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Вот здесь http://pycon.blip.tv/file/3359630/ автор greenlet утверждает, что ему удалось создать около 1000 тредов, после чего ОС сказала ‘Извини, но я больше не буду делать тебе треды’ :)
Кстати, рекомендую посмотреть видео целиком. Очень интересно и как раз в тему.
В частности он упоминает еще одну возможность - неблокирующий ввод/вывод. Если вам так противны треды, то можете попробовать этот подход.



Офлайн

#5 Авг. 27, 2010 01:09:17

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Создание сервера с неограниченым числом подключений

Сначала изучаем неблокирующие сокеты и select.select.
Потом, поэкспериментировав на кроликах и проникшись идеей, выбираем между более оптимальными реализациями.



Офлайн

#6 Авг. 27, 2010 01:22:48

CryptSpirit
От:
Зарегистрирован: 2010-05-05
Сообщения: 88
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Ed, как не странно но то же самое удалось и у меня. Это где то 1020 тредов. Видео не позволяет посмотреть мой мобильный диал-ап. Я так понял что асинхронизация + нагрузка на один тред определенного числа конектов и можно заполнять анкету в книгу рекордов. Просьба делать ссылки на хотя бы обрывки кода.

ладно оцените мой “почерк”

Сервер

#!/usr/bin/python
import socket,time,threading
HOST = 'localhost'
PORT = 5000
class OnConnect(threading.Thread):
def __init__(self,conn,addr,indexx):
threading.Thread.__init__(self)
self.conn=conn
self.addr=addr
self.indexx=indexx
self.start()
def run(self):
while 1:
try: data = self.conn.recv(1024)
except:
break
else:
if (not data) : break
self.conn.send(data)
time.sleep(0.1)
self.conn.close()
print self.indexx,'-',self.addr[0],':',self.addr[1],'(',time.asctime(time.gmtime(time.time())),')'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print 'Run in',time.asctime(time.gmtime(time.time()))
print 'Host: ',HOST
print 'port: ',PORT
s.listen(1)
d=0
threading.stack_size(0x100000)
while 1:
conn, addr = s.accept()
d=d+1
print d,'+',addr[0],':',addr[1],'(',time.asctime(time.gmtime(time.time())),')'
OnConnect(conn,addr,d)
time.sleep(0.1)
conn.close()
клиент для краш теста

import socket,threading,time
class TestServ(threading.Thread):
def __init__(self,s):
threading.Thread.__init__(self)
self.s=s
self.start()
def run(self):
for i in range(1000):
self.s.send('x')
data=self.s.recv(1024)
time.sleep(1)
self.s.send('exit')
self.s.close()
port=5000
threading.stack_size(0x100000)
for i in range(10000):
print i
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('localhost',port))
TestServ(s)
time.sleep(0.1)
Не пинать я с апреля на питоне



Отредактировано (Авг. 27, 2010 01:31:00)

Офлайн

#7 Авг. 27, 2010 10:02:11

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

Посмотрите в код фреймворка/сервера Tornado и почитайте о проблеме 10k - http://www.kegel.com/c10k.html. Также познавательным будет знакомство с сервером YAWS - http://yaws.hyber.org.

Андрей Светлов
Потом, поэкспериментировав на кроликах и проникшись идеей
Давайте все-таки на кошках =)



Офлайн

#8 Авг. 27, 2010 14:37:51

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

CryptSpirit
Ed, как не странно но то же самое удалось и у меня. Это где то 1020 тредов.
Странно. А это точно про треды. потому что 1021 это очень похоже на ограничение по файловым дескрипторам.
У меня, например оно 1024. Минус 3 стандартных (stdin, stdout, stderr) получаем 1021.
Попробуйте увеличить количество открытых файлов для процесса.
Но вообще при невозможности создать тред должен получиться Exception такого вида:
Traceback (most recent call last):
File "./server.py", line 55, in <module>
thread.start()
File "/usr/lib/python2.6/threading.py", line 474, in start
_start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread
У меня это происходит при попытке создания треда номер 380.

ладно оцените мой “почерк”

Не пинать я с апреля на питоне
Как же тогда оценивать :) ?



Отредактировано (Авг. 27, 2010 14:53:22)

Офлайн

#9 Авг. 27, 2010 16:09:49

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

CryptSpirit
Просьба делать ссылки на хотя бы обрывки кода.
Вот, что у меня получилось используя eventlet monkey_patch. Это по сути аналог вашего сервера - уберите вызов monkey_patch - получите полный аналог.
import eventlet
eventlet.monkey_patch()

import sys
from threading import Thread
import socket

HOST, PORT = 'localhost', 5000

def handle(index, addr, conn):
while True:
data = conn.recv(1024)
if not data:
break
conn.send(data)
print 'client %i disconnected' % index

if __name__ == '__main__':

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)

print 'Server is waiting for connections on %s:%d' % (HOST, PORT)

index = 0
while True:
index += 1
conn, addr = sock.accept()
print "client connected from %s:%s. Creating thread %d" % (addr[0], addr[1], index)
thread = Thread(target=handle, args=(index, addr, conn))
thread.start()
Сломался клиент на создании треда 2993:
2993
Traceback (most recent call last):
File “./client.py”, line 25, in <module>
TestServ(s)
File “./client.py”, line 11, in __init__
self.start()
File “/usr/lib/python2.6/threading.py”, line 474, in start
_start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread

Если его также пропатчить, то думаю будет гораздо больше.

PS: Да, я сделал еще ulimit -n 10000 предварительно. Иначе отваливалось по ‘too many open files’



Офлайн

#10 Авг. 27, 2010 16:22:07

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

Создание сервера с неограниченым числом подключений

можно попробоват ьиспользовать селект

Офлайн

  • Начало
  • » Network
  • » Создание сервера с неограниченым числом подключений[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version