Найти - Пользователи
Полная версия: Создание сервера с неограниченым числом подключений
Начало » Network » Создание сервера с неограниченым числом подключений
1 2 3 4 5
Alex_Kutsan
как в аське. прошу прощения за формулировку.
Ладно, фиг с ним , вот код, если поможет буду рад.
Сервер:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket,thread
HOST = ""
PORT1 = 1111
a=0
users = []
susers =[]
conect= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conect.bind((HOST, PORT1))
myIP1= conect.getsockname()
def OUTme():
global users,l
while 1:
inp = raw_input("")
if inp == "print l":
print l
elif inp == "print users":
for x in users:
print x[0].encode('UTF-8')
elif inp == "send":
sms = raw_input("sms:")
sms = "From ADMIN: " + sms
for x in users:
x[1].send(sms)
else:
pass
def lsttostr(lst):
str = ""
for x in lst:
str = str + x[0] + ","
return str
def get_user(a):
global l,users
l = len(users)
l = str(l)
print "на сервере ",l," пользователей"
print"Прослушиваю порт"
conect.listen(1)
sub,ip = conect.accept()
print "какоето шевеление"
name = sub.recv(1024)
print name,ip , "Присоеденился к серверу"
sub.send(l)
print l
if l =="0":
users.append([name,sub,ip])
susers.append([name,sub,ip])
else:
strusers = lsttostr(users)
sub.send(strusers)
ans = sub.recv(1024)
if ans =="1":
user2 = sub.recv(1024)
print "Принято"
user2 = int(user2)
users[user2][1].send("Кто-то к вам присоеденился")
print "отправлено 1"
sub.send("Вы присоеденились")
print "отправлено 2 "
thread.start_new(SMS,(sub,users[user2][1]))
thread.start_new(SMS,(users[user2][1],sub))
users[user2-1:user2+1]=[]
susers.append([name,sub,ip])
print "2 пользователя соеденено"
else:
users.append([name,sub,ip])
susers.append([name,sub,ip])
get_user(a)
def SMS(user1,user2):
while 1:
sms = user1.recv(1024)
if sms:
user2.send(sms)
thread.start_new(get_user,(a,))
thread.start_new(get_user,(a,))
thread.start_new(get_user,(a,))
OUTme()
conect.close()
Извиняйте за недоработки и множество мусорного кода. Но както потерял интерес к этому чату, переключился на другое. Под виндой работает, но вервер рисует крокозябры, нудно перекодировать в юникод каждую выводящююся строку, под линуксом прекрасно пишет русские буквы. Да и функция OUTme() не пашет, не разобрался ещё почему, всё мозги и руки не доходят.
Есть ещё несколько багов. Но в целом программа работает, с неограниченым количеством клиентов. И позволяет клиентам выбирать с кем они хотят общятся.

А вот и клиент.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket,thread
a=0
HOST = "vsrmischat.homeunix.com"
PORT=1111
conect = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conect.connect((HOST,PORT))
print "connect to ", PORT
myIP= conect.getsockname()
name = raw_input("What is your nsme? ")
conect.send(name)
l = conect.recv(1024)
print l
l=int(l)
def strtolist(string):
lst = []
i=0
k=0
n=0
while k!= len(string):
if string[k] == ",":
lst.append(str(i) + " " + string[n:k])
n=k+1
i = i+1
if k ==len(string)-1:
lst.append(str(i) + " " + string[n:k+1])
k = k+1
return lst
def IN(a):
while 1 :
sms = conect.recv(1024)
if sms:
print sms
def OUT(a):
while 1:
sms = raw_input("")
conect.send(sms)
def ch():
u = raw_input("Input number of user You want to speek")
try: u = int(u)
except ValueError:
print"Try again"
u = ch()
if u in xrange(0,l):
pass
else:
print"Try again"
u = ch()
u = str(u)
return u
def Ans():
ans = raw_input("If you want to choose user to speak press 1, if you want to wait wile sobe body chose youpress2")
if ans =="1" or ans == "2":
pass
else:
print"Try again"
ans = Ans()
ans = str(ans)
return ans
if l==0:
print"You is only one user, whait some body"
sms = conect.recv(1024)
if sms:
print sms
print" _-_-_-_-_-_--___--__--__"
else:
print"Sorry, maybe server is DOWN"
exit()
else:
print "there are users, a waiting you to chat them"
us = conect.recv(1024)
lstus = strtolist(us)
for x in lstus:
print x
ans = Ans()
conect.send(ans)
if ans =="1":
u = ch()
conect.send(u)
sms = conect.recv(1024)
if sms:
print sms
print" _-_-_-_-_-_--___--__--__"
else:
print "Sorry, maybe server is DOWN"
exit()
else:
print"SO... Wait..."
sms = conect.recv(1024)
if sms:
print sms
print" _-_-_-_-_-_--___--__--__"
else:
print"Sorry, maybe server is DOWN"
exit()
thread.start_new(IN,(a,))
OUT(a)
conect.close()
Никак не могу справится с такой проблемой. при отключении кллиента. у сервера Тред выдаёт ошибку. Надо наверно через try except.
Хмммм. вот писал только что и в голову мысль пришла. Сейчас будет ещё многа букв. Так сказать дополню ещё своим вопросом.
Я столкнулся с проблемой налаживания связи меж клиентом и сервером, ведь именно тогда когда клиент передаёт СООБЩЕНИЕ сервер тоже должени принимать именно СООБЩЕНИЕ, а не например ИМЯ или ещё чего нибудь, я криво -косо справился с этой проблемой, но больно некрасиво както. И вот подумал. А что если клиент будет перед посылкой данных отсылать “ключь ” что это за данные, а сервер будет сначала принимать ключ и уже зависимости от него делать с данными то что надо. Я конечно врятли открыл америку, но мне кажедтся если наладить такого рода связь , то она будет понадёжнее чем то что я (см мой код) понаписывал.
Ed
CryptSpirit
… Я новичке и при всем разнообразии стилей написания кодов меня реально волнует только производительность. Поправте меня если я не прав.
Вы неправы в подходе. Какой смысл профилировать никому не нужные циклы? Вот возьмите и попрофилируйте реальную программу, да хоть и эту. Я сильно удивлюсь, если += там сильно повлияет на производительность. А, как известно, профайлить нужно то, что влияет. А += выразительнее, только поэтому я его и использовал. Но уж если мне профайлер покажет, что мой сервер из-за этой конструкции тормозит, то я поменяю ее на другую. Только в этом случае, а не из-за того, что она медленнее сама по себе. Вот так.
CryptSpirit
Ed
не из-за того, что она медленнее сама по себе
Что то я опять туплю. У меня логическая цепочка:
Тормозит в примере (где меняется только конструкция “присвоения”) то тормозит везде. Вопрос по профайлу как мне профайлить мой сервер (его узлы). Я хочу показать вам цифры (да если честно и сам посмотреть на них с разными изменениями).
Ed
Вы неправы в подходе
Подход получить производительный код. Зная что Питон не очень уж и быстр использовать уловки для того что бы не потерять и той не большой скорости я считаю рациональным. А использовать эти конструкции ибо они “эстетичнее” смотряться мне кажиться излишней. Но это имхо. Просто ну не понимаю. Пусть даже одна из задач Питона читабельный для других людей код но какой программист будет вредить своей программе?
Ed
http://www.python.org/dev/peps/pep-0008/
Почитав это чтиво от некоторых абзацев стало тошнить. Напомнило правила форматирования в Ворде. Я пишу программу, а не оформляю рекламный буклет. Особенно отвратительно стало от отступов. Опять же имхо программирование это алгоритм, а не форматирование текста. Какая разница как я буду описывать импорты? В начале я думал что Питон направлен на уменьшения размера конструкция, а здесь в точности да наоборот.
Alex_Kutsan
Но в целом программа работает, с неограниченым количеством клиентов
А как сие было проверено? По коду что то не похоже на то.
Alex_Kutsan
проблемой. при отключении кллиента. у сервера Тред выдаёт ошибку
Это не странно.
Lexander
CryptSpirit
Подход получить производительный код. Зная что Питон не очень уж и быстр использовать уловки для того что бы не потерять и той не большой скорости я считаю рациональным. А использовать эти конструкции ибо они “эстетичнее” смотряться мне кажиться излишней. Но это имхо. Просто ну не понимаю. Пусть даже одна из задач Питона читабельный для других людей код но какой программист будет вредить своей программе?
Все относительно, простите за банальщину.
Есть несколько критериев, важных в создании программ, например: производительность программы, читаемость кода, скорость создания программы и пр.

Производительность оценивается на уровне отдельных модулей и алгоритмов. Это потому, при оптимизации сначала находят узкое место в системе, и, часто оказывается, что это подсистема ввода/вывода. Ваша “неоптимальная” программа простаивает, ожидая поступления данных с жесткого диска, сети или действий пользователя. Поэтому нет смысла ее оптимизировать, причина “тормозов” в другом месте и все усилия следует приложить туда.

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

CryptSpirit
Почитав это чтиво от некоторых абзацев стало тошнить. Напомнило правила форматирования в Ворде. Я пишу программу, а не оформляю рекламный буклет. Особенно отвратительно стало от отступов. Опять же имхо программирование это алгоритм, а не форматирование текста. Какая разница как я буду описывать импорты?
Эти правила есть в каждом языке, даже на проекты могут создаваться свои “соглашения о кодировании”. Это очень полезно в групповой разработке.
Составляя PEP-0008, авторы уже продумали за вас и составили такое соглашение о кодировании.
Вы, работая один, можете сами для себя вырабатывать (явно или неявно - в уме) правила составления кода и они могут отличаться от общепринятых или дополнять их (например, вы можете использовать запись а = а + 1 вместо а+=1). Но, как только к вам присоединяется хотя бы 1 человек, вам нужно договориться. Иначе будет глупо потрачено время на разбор кода и понимание алгоритмов.
Это, в том числе, очень актуально при оптимизации кода или расширении функционала.

Если вы с этим не согласны, предлагаю эксперимент. Вы собираетесь с друзьями и каждый пишет (не важно на каком языке, главное, чтобы все писали на одном и том же) код модуля. Потом обмениваетесь модулями и каждый вносит какие-то значимые изменения и составляет свое мнение о чужом коде, фиксирует время, которое было потрачено на разбор чужого кода. Потом модуль возвращается к первоначальному автору и тот снова составляет оценку и фиксирует время.
Далее вы собираетесь вместе и договариваетесь о правилах написания кода, повторяете эксперимент и сравниваете результаты. Выводы сделаете сами.
Ed
CryptSpirit
Что то я опять туплю. У меня логическая цепочка:
Тормозит в примере (где меняется только конструкция “присвоения”) то тормозит везде. Вопрос по профайлу как мне профайлить мой сервер (его узлы). Я хочу показать вам цифры (да если честно и сам посмотреть на них с разными изменениями).
Я верю, что по сравнению с a = a + 1 a+=1 тормозит. Но в реальном приложении это скорее всего будет несущественно, поскольку основное время поглощается более медленными вещами. Вот, например, вы отпрофайлили свой сервер и увидели, что 99% времени у вас жрет создание вашего объекта треда и запуск его метода run. А конструкция a+=1 есть 0.00002%. Это все условно, естетсвенно. Вы поменяете ее на a = a +1 и увеличите производительность этой конструкции в 2 раза, а производительность приложения на 0.00001%. И какой в этом смысл? Ускорять имеет смысл то, что наиболее медленно. Питон - это не ассемблер и в нем производительность не всегда важна. Для меня, например, гораздо большее значение имеет читабельность кода. В 99% случаев в области, где я работаю производительности Питона хватает. Когда не хватает - беру профайлер и профилирую. Только не присваивания профилирую, а приложение в целом, находя критичные по производительности участки и ускоряя их. А вот код, написаный непонятно создает гораздо большие трудности в сопровождении. Есть у нас и такой. Пережитки прошлого, так сказать.

Ed
Подход получить производительный код.
Это цель. А подход обычный для Питона, и не только - сделать работающую программу, которую не стыдно людям показать и потом профилировать ее. Не нужно профилировать неработающий код - это бесполезное занятие.

Почитав это чтиво от некоторых абзацев стало тошнить.
Это не чтиво, это общепринятые нормы оформления питонового кода. Меня обычно подташнивает при взгляде на код, сделанный кое-как. И смею предположить, что не только меня. А вот при взгляде на код, сделаный по тем правилам почему-то нет. Почему бы это?

Я пишу программу, а не оформляю рекламный буклет. Особенно отвратительно стало от отступов.
Хм. А что с ними не так?

Опять же имхо программирование это алгоритм, а не форматирование текста. Какая разница как я буду описывать импорты?
Алгоритм - это идея. Программа - это ее выражение. Это как в обычном языке. Большинству будет наплевать какие у вас мысли, если вы не сможете их выразить вслух, либо на бумаге, пользуясь общепринятыми языковыми нормами. PEP8 - это такие же общепринятые нормы.
Насчет импортов - очень хороший и показательный вопрос. Вы пользуетесь системой контроля версий для хранения вашего кода? Если да, то посмотрите насколько менее понятен diff при изменении строки с кучей импортов и строки с одним. Кстати, и остальные вещи в PEP8 - это результат практики программирования, а не какие-то кем-то специально придуманые дурацкие правила. То, что они вам непонятны не значит, что они бессмысленны.

В начале я думал что Питон направлен на уменьшения размера конструкция, а здесь в точности да наоборот.
В Питоне читабельности кода придается большое значение. И это хорошо. Это делает программы на питоне понятными и красивыми, а программирование - приятным. И таки да - чаще программы на Питоне короче аналогов на других языках.

С другой стороны вас никто не заставляет следовать этим правилам - пишите как вам угодно. В конце концов вы сами попросили оценить ваш код. Не понравился мой совет - не пользуйте, делов-то.
CryptSpirit
Ed
Вы пользуетесь системой контроля версий для хранения вашего кода?
Нет. Я занимаюсь панорамированием с 9 класса. Потом был универ (химическая специальность). Так сложилость что к концу учебы у меня появилась работа связаная с компьютерами. Я уже второй год использую линукс. А теперь не сложно догадаться в каких целях мне нужен Питон. Контроль версий это хорошо но не в моем случае. потому я вас не понял.
Ed
В конце концов вы сами попросили оценить ваш код
Да. И рад что получил больше чем хотел (а именно задал наболевшие вопросы и узнал о этих правилах написания кода).

Все огромное спасибо за объяснения. Я все понял. Немного не согласен (в мелочах). Но оставлю эти несогласия при себе, потому что надо же остаться при своем мнение хотя бы в чем то ))). Был промежуток когда я писал небольшие обрывки кода и далеко не на питоне. В то время и превилась идея того что все в нем должно быть придельно быстро.
Ed
Ну вот и хорошо, раз поняли. Будет желание продолжить - милости просим. После pylint rate > 9 :)
Alex_Kutsan
CryptSpirit
А как сие было проверено? По коду что то не похоже на то
Почему же не похоже, очень даже похоже. Сначала идут 3 треда get_user( одновременно к серверу могут подрубится и выбирать себе собеседника 3 человека) как только они быбирут собеседника то создастся новый тред общения этих 2 клиентов. А тред get_user освободится и будет ждать новых людей. А проверено было сие на 1 машине, включил сервер. и стал включть клиенты. пока мне не надоело, навключал много, уж простите но неограниченое количество включитья не мог. Но опять же смотрите выше, как только клиент выбрал собеседника создаётся НОВЫЙ тред их общения. Так что сколько пар Клиентов на сервере столько и тредов.
Попробуйте запустить код, рабочий( не считая тех недороботок. чтоя описывал выше) И желательно под линуксом. Потому что под виндой сервер будет по Китайски ругатся
CryptSpirit
Alex_Kutsan
Клиентов на сервере столько и тредов
Если вы читали посты выше основная проблема создание тредов. В этом ограничение. Если вы напишите клиент который автоматом подрубит определенное число клиентов к серверу то сможете еще иуказать цифорки. Смотрите мой код. Там пример клиента для краш тестов. У меня узким местом оказались треды свыше 1021 машины посылали меня на…
Alex_Kutsan
Хммм, тоггда могу предложить неограниченое кол-во клиентов с 1 тредом. НО! все клиенты будут общятся так сказать как в старых добрых чатах. Тоесть если кто-то что-то отправил , то получат все. и сервер не может толком индентифицировать клиента.
Щяс попробую наваять такой код, но за работо способность не ручаюсь
сервер:
#!/usr/bin/env python
import socket,thread
HOST = ""
PORT = 1111
a=0
users = []
conect= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conect.bind((HOST, PORT))
myIP1= conect.getsockname()
def get_user(a):
while 1:
conect.listen(1)
sub,ip = conect.accept()
name = sub.recv(1024)
users.append([name,sub,ip])
print name , "connected to us"
OUT("connected to us",name)
def IN(a):
while 1:
name = conect.recv(1024)
sms = conect.recv(1024)
if sms:
OUT(sms,name)
print name, " ", sms
def OUT(sms,name):
for x in users:
x[0].send(name)
x[0].send(sms)
def OUTme():
sms = raw_input("")
OUT(sms,"Admin")
thread.start_new(get_user,(a,))
thread.start_new(IN,(a,))
OUTme()
conect.close()
И клиент
#!/usr/bin/env python
import socket,thread
HOST = "localhost"
PORT=1111
conect = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conect.connect((HOST,PORT))
print "connect to ", PORT
myIP= conect.getsockname()
name = raw_input("Input your name")
conect.send(name)
a=0
print name,"Chat is begin"
def OUT(a):
while 1:
sms = raw_input("")
conect.send(name)
conect.send(sms)
def IN(a):
fname = conect.recv(1024)
fsms = conect.recv(1024)
if fsms:
print fname, " " , fsms
thread.start_new(IN,(a,))
OUT(a)
conect.close()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB