2013-04-11 23 views
7

Bir udp sunucu/istemci uygulaması üzerinde çalışıyorum.Recv_from işlevini engelleme yapma

İstemciden herhangi birinin kapalı olup olmadığını bulmak için, sunucu istemciye bir el sıkışması iletisi gönderir. Daha sonra sunucu, istemcinin etkin olduğundan emin olmak için istemcinin yanıt vermesini bekler. Bunun için, istemci yanıt vermediği sürece sunucu, recvfrom() numaralı çağrıya engel olur, ancak istemci kapalıysa, sunucu recvfrom() numaralı çağrıya sonsuz olarak engeller.

Sunucumda böyle bir işlev uygulamak istiyorum, böylece aramayı belirli bir süre için recvfrom() bekler (örneğin 2 saniye). İstemciden 2 saniye içinde hiçbir veri alınmadıysa, istemcinin öldüğü ve recvfrom() döndürdüğü kabul edilir.

Bunu yapmanın bir yolu var mı? İnternette arama yaptım, ancak hiçbir veri alınmadığında hemen döndüren MSG_DONTWAIT bayrağının ayarlanması gibi çözümler buldum, ancak benim durumumda, recvfrom()'un hemen geri dönmesini istemiyorum, ancak belirli bir süre için veriyi beklemiyorum. belirli süre, recvfrom() işlevinin yeniden ayarlanması gerekir.

Herhangi bir yardım için teşekkür ederiz.

+1

Güvenilir bir servis uygulamak istiyoruz. [recvfrom() işlevini] (http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/rcvf.htm) 'da ayarlayabilirsiniz. [fcntl() veya ioctl() işlevini kullanarak engelleme modu] (http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/ rcvf.htm). Ayrıca bunu okuyun [UDP güvenilir veri hizmeti uygulaması] (http://stackoverflow.com/questions/8353970/udp-reliable-data-service-implementation) –

+1

checkout ** [c - winsock recvfrom için zaman aşımını ayarla - Yığın Taşması] (http://stackoverflow.com/questions/1824465/set-timeout-for-winsock-recvfrom)** –

+1

Ayrıca [check out] (http://msdn.microsoft.com/en-us/library/windows/desktop /ms740120%28v=vs.85%29.aspx) .it, net bir açıklamayı ** WSARecv() ** verir (işlev için kuralları engeller). –

cevap

8

En kolay yol, söz konusu yuva için bir alma zaman aşımı belirlemek üzere setsockopt() kullanmaktır. Bunun için

SO_RCVTIMEO kullanılmıştır.

recvfrom()'a iletilen bir yuva için zaman aşımı ayarlandıysa, veri alınmadığında bu zaman aşımından sonra işlev geri döner. Örneğin

, 10 saniyenin zaman aşımı oku set (gerektiğinde setsockopt() gelen returnValue hata denetimi ekle): Detaylar on Windows please see here ve on Linux see here ve/veya here (POSIX) için

#include <sys/types.h> 
#include <sys/socket.h> 

... 

struct timeval read_timeout; 
read_timeout.tv_sec = 0; 
read_timeout.tv_usec = 10; 
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout); 

.

+0

Çalıştı, çok teşekkür ederim :) – Ayse

+3

ya da soketinin bir zaman aşımı içinde okunabilir bir duruma girmesini beklemek için 'select()' yi kullanın, daha sonra 'recvfrom()' sadece soket gerçekten okunabilir olduğunda, veri okumak için mevcut olduğunu gösterir. –

+0

"select" işlevini kullanıyorum. Çok daha iyi kontrol elde edersiniz ve birden çok soketle çalışmayı daha kolay hale getirirsiniz. –