2010-11-21 14 views

cevap

8

Bağlantı noktasına bind'u deneyin ve EADDRINUSE için errno numaralı telefondan kontrol edin. Tek yol budur, çünkü böyle bir kontrolün doğru olması atomik olmalıdır. Ayrı bir kontrol yaptıysanız, kullanımda olmadığını tespit ettikten sonra limana bağlanmayı denediniz, başka bir süreç araya girme zamanında limana bağlanarak tekrar başarısızlığa neden olabilir. Benzer şekilde, ayrı bir denetim yaptıysanız ve zaten kullanılmakta olan bağlantı noktasını bulursanız, bunu kullanan işlem aradaki bağlantı noktasını kapatabilir, çıkışa ya da çökebilir ve sonuç yanlış sonuç verebilir.

Tüm bunların (kısa bir cevap yerine uzun bir cevap yazmamın nedeni), "Bunu yapabilir miyim?" Diye kontrol etmenin doğru ve sağlam yoludur. hemen her zaman için yapmayı deneyin ve arızayı kontrol edin. Başka herhangi bir yaklaşım, yarış koşullarına yol açabilir ve çoğu durumda, yarış koşulları (muhtemelen sizin olmasa da) yarış koşulları güvenlik açıklarıdır.

5

bind() başarısız olur:

başarı üzerinde

, sıfır döndürülür. Hata durumunda -1 döndürülür ve errno uygun şekilde ayarlanır.

EADDRINUSE Verilen adres zaten kullanımda.

+0

Ancak bu şekilde bir sunucu soketi oluşturmam gerekiyor ... bind() ... daha sonra kapatın ... Daha basit bir yol var mı? – wong2

+2

Hayır, bu tek uygun yol. Neden onu kapatmak istiyorsun? Onu zaten bağlamış olmanız durumunda dinlemeniz için kullanın - bu süre zarfında başka bir işlem bu bağlantı noktasına bağlanabileceğinden daha sonra kullanılabilir olup olmayacağını bilemezsiniz. – ThiefMaster

+0

@ wong2: Cevabımı oku. Bağlantı noktasını bağladığınızda ve kullanmaya hazır olana kadar bağlı kalmazsanız, sorunun cevabını belirlemenin hiçbir yolu yoktur ("Bağlantı noktası zaten kullanılıyor mu?"). Önceden kontrol edilmesi (ve sonra serbest bırakılması) yanlış cevaplara tabidir. –

0

Başka bir yaklaşım: localhost numaralı bağlantı noktasında bu bağlantı noktasına bağlanmayı deneyin.

+1

Bazı nedenlerden dolayı kötü bir fikir ve bu testin başarısız olabileceği yollarını ekleyin ve cevabınız değerli olabilir ... –

+1

a) Çalışan sunucu belirli bir arayüzü dinleyebilir ve 'localhost' ile bağlantı kontrol etmez. ; b) zaman aşımları; c) TCP sunucusunu ayrı bir işlem olarak başlatmak için bağlantı noktasını kontrol etmek için bu yöntemi kullandım (hataların doğru hata kodlarını döndürmediği için, bunu kontrol etmenin tek yolu buydu). – khachik

+0

Bu arada, (a) bağlantı noktasını bağlayarak atomik olarak test etseniz bile sorun olur. 0.0.0.0: tarihinde bir bağlantı kurarsanız bile, başka bir işlem zaten aaa.bbb.ccc.ddd: bağlantı noktasını (harici ağ adresinin ipini) bağlamış olabilir. –

0

Sadece bir soket oluşturmak ve çağrı bağlama gösterirse(). Eğer bind() başarıya ulaşırsa, dinlemeye() devam edin, aksi takdirde varsayılan bağlantı noktasına geçmek, hata mesajı yazdırmak ve kullanıcı etkileşimini beklemek veya en azından oturum açmak ve çıkmak gibi bazı hata işleme prosedürlerini gerçekleştirmelisiniz.

İlgili konular