Nowe posty

xx Problem ze sterownikami. (5)
2024-04-13, 21:25:16
xx Instalacja xfce4 (2)
2024-04-13, 16:20:17
xx Serie kompilacji bez instalacji dla “emerge” w Gentoo (2)
2024-04-08, 18:40:04
xx Plasma 6 w Neonie ssie trochę mniej ... (17)
2024-04-05, 10:03:46
xx Problem z Linux Lite po instalacji (3)
2024-04-03, 14:23:40
xx Jak właczyć num locka przy starcie systemu debian 12? (12)
2024-04-02, 17:43:54
xx Brak dźwieku w systemie. (5)
2024-04-02, 16:13:41
xx Dystrybucja pod HP Omen (7)
2024-03-29, 11:33:05
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
xx Ile pingwinów? (1)
2024-03-27, 08:59:24

Autor Wątek: Python- dziwny problem z akceptacją połączeń na serwerze  (Przeczytany 5209 razy)

Ksanderon

  • Gość
mam dziwny problem z kodem serwera w pythonie - w pewnym momencie, gdy klientem w kółko zadaję pytanie(ok. tysiąca razy na sekundę) serwer nagle przestaje akceptować połączenia- nie daje przy tym żadnych ostrzeżeń, a po kilku-kilkunastu sekund później sam z siebie pozwala się znowu łączyć.


import socket
import thread
import sys

def recvall(newsock):
data=''
try:
while True:
new_data=newsock.recv(1024)
data+=new_data
if data[-4:]=="\\r\\n\\r\\n":
return data
except socket.timeout:
print 'timed out'
finally:
return data

def run(newsock,addr):
#print addr
newsock.settimeout(0.01)
result=recvall(newsock)
newsock.settimeout(None)
newsock.sendall(result)
newsock.close()

def open_sock(host,port):
try:
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host,port))
return sock
except socket.error, (value,message):
if sock:
sock.close()
print "Could not open socket: " + message
sys.exit(1)

def start(host,port):
sock=open_sock(host,port)
sock.listen(5)
print 'Started on',port
i=0
while True:
i+=1
if i%1000==0:
print i
thread.start_new_thread(run, sock.accept())

start('',1234)
sprawdziłem czy problem nie leży przypadkiem po stronie wątków(które nie do końca mnie się podobają) wykonując kod synchronicznie(ten sam problem się zdarza) oraz zamieniając na fork(który strasznie się ślimaczył, przez co w sumie nie wiem czy tu też taka sytuacja występuje).

Jak pisałem w C takie rzeczy to się z takim czymś nie spotykałem, na prawdę nie wiem gdzie jest problem...

Może kolejka się zapycha lub na accept sobie czeka nie wiadomo na co? Jak to sprawdzić?

Zdarza się to dużo częściej jeśli klientów jest kilku i tak sobie pytają.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3056
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Python- dziwny problem z akceptacją połączeń na serwerze
« Odpowiedź #1 dnia: 2011-06-26, 22:18:27 »
Może sock.listen(5)? Tutaj maksymalna kolejka (czyli czekające pomiędzy wpadnięciem a rozdysponowaniem do wątku) to 5 pakietów. W pewnym momencie może Python się nie wyrabia z generacją wątków, kolejka się przepełnia i gubi połączenie?

Tyle że w sytuacji, gdy Python wolniej generuje wątki niż przychodzą pakiety to zapcha kolejkę dowolnej długości...
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

Ksanderon

  • Gość
Python- dziwny problem z akceptacją połączeń na serwerze
« Odpowiedź #2 dnia: 2011-06-27, 10:43:08 »
no tak, tylko, że wtedy po wyłączeniu wszystkich klientów kolejka powinna bardzo szybko się odblokować- a taka zwiecha potrafi czasem nawet 30 sekund trwać.

Offline vanhelzing

  • Users
  • Prawie jak Guru
  • ****
  • Wiadomości: 314
    • Zobacz profil
Python- dziwny problem z akceptacją połączeń na serwerze
« Odpowiedź #3 dnia: 2011-06-27, 15:26:54 »
Tworzenie i usuwanie tysiąca wątków na sekundę w pythonie, musi kosztować. To normalne, że się zamuli. Jeżeli masz niewiele klientów, to lepsze jest rozwiązanie wątek/klient oraz keepalive (bez wznawiania połączenia przy każdym żądaniu), albo użyć selecta (epoola) na gniazdkach i wtedy bez wątków.

Ten szablon którego użyłeś jest bardzo ładny i czysty, ale absolutnie bezużyteczny przy większym obciążeniu. W tej chwili to działa jak fork-bomba.