2011-06-16 11 views
9

Python'da yeniyim ve şu anda TCP/IP (bir hava istasyonu) üzerinden bir aygıtla iletişim kuran bir komut dosyası olarak çalıştırılmak üzere bir python soketi yazması gerekiyor.
Aygıt Sunucu Tarafı olarak işlev görür (IP üzerinden dinleme: PORT, bağlantı kabul etme, istek alma, veri aktarma).
Sadece bir mesaj atmam, cevabı almam ve daha sonra huzurlu ve güzelce kapatmam ve soketi kapatmam gerek. Python: Bloke olmayan soket veya Asynchronos I/O

try: 
    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(1) 

try: 
    comSocket.connect(('')) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(2) 

comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r\r') 
comSocket.recv(128) 

comSocket.send('1I\r\r3I\r\r4I\r\r13I\r\r5I\r\r8I\r\r7I\r\r9I\r\r') 

rawData = comSocket.recv(512) 

comSocket.shutdown(1) 
comSocket.close() 

yaşıyorum sorundur:
iletişim kanalı güvenilmez, cihaz yavaş. Yani, bazen 0 (sadece bir ACK) mesajı ile cihaz yanıtı, kodum donacak ve sonsuza kadar cevap bekleyecektir.
Bu kod parçası SOCKET'i içeren bölümü içerir, tüm kod CRON altında çalıştırılacak, bu nedenle donma istenen bir davranış değildir.

Sorum şu: kod dondurmak ve sonsuza beklemez, böylece o davranışı işlemek için Python en iyi yolu olacağını ancak (ya da bu tür) bir sonraki gönderme geçmek dener Ne
.

+5

Python için [Twisted] (http://twistedmatrix.com/) kitaplığına bir göz atmalısınız. Bu çok daha kolay hale getirecek asenkron ağ için bir çerçevedir. – Andrea

+0

Twisted kütüphanesi çalışırken, bir mesaj için bütün bir kütüphane biraz aşırı görünüyor. Belki de CRON'un soket iletişiminizin ayrı bir iş parçacığı ile devam ettiği bir alt işlem açmış olmanız gerekir. Bu şekilde engelleme sorununu engelleyeceksiniz. – chisaipete

+0

@Andrea Gönderilene benzer bir sorum var. Twisted, Sunucu Tarafı için tasarlanmamış mı? İstemci tarafında kullanmak için nasıl değiştirilir? – Hangon

cevap

0

deneyin, soket üzerinde bir zaman aşımı koyarak almadan önce:

comSocket.settimeout(5.0) 
try: 
    rawData = comSocket.recv(512) 
except socket.timeout: 
    print "No response from server" 
3

Bunun için eventlet ve yeşil konuları öneriyoruz.

Twisted iyi bir kütüphane ama böyle basit bir kullanım durumu için biraz dik öğrenme eğrisi.

Bazı örneklere bakın here.

11

Russel kodu gibi bir zaman aşımı yaklaşımını deneyebilir veya aşağıdaki kodda gösterildiği gibi engelleme olmayan bir soket kullanabilirsiniz. socket.recv'da hiçbir zaman engellenmeyecek ve istediğiniz kadar tekrar etmek için bir döngü içinde kullanabilirsiniz. Bu sayede programınız zaman aşımına uğramaz. Bu şekilde, verilerin kullanılabilir olup olmadığını sınayabilirsiniz, değilse başka şeyler yapabilir ve daha sonra tekrar deneyebilirsiniz.

socket.setblocking(0) 
while (retry_condition): 
    try: 
     data = socket.recv(512) 
    except socket.error: 
     '''no data yet..''' 
İlgili konular