2016-04-27 49 views
1

所以我試圖解決在C#.NET編程的套接字,但沒有好的文章/指南關於它從我看到和發現(甚至官方MSDN網站已經過時的代碼)。我試圖按照這個鏈接here,但由於它已經過時,我不確定那裏的代碼是否被認爲是好的做法。 所以,有這樣的代碼:在每種方法中初始化一個新套接字是件好事嗎?

public void StartListening() { 
    Socket listener = new Socket(localEP.Address.AddressFamily, 
    SocketType.Stream, ProtocolType.Tcp); 

    listener.BeginAccept(new AsyncCallback(acceptCallback), listener); 
} 

再有就是這個代碼:

public void acceptCallback(IAsyncResult ar) { 
    Socket listener = (Socket) ar.AsyncState; 
    Socket handler = listener.EndAccept(ar); 
} 

爲什麼acceptCallback初始化一個新的插座?爲什麼所有的方法都要初始化一個自己的套接字?只有一個這樣的全班私人插座不是更好嗎?

private Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);?爲什麼它首先創建一個偵聽器套接字然後處理套接字?這是什麼意思?另外,在BeginAccept方法中作爲參數傳入的偵聽器會發生什麼?從外觀上看,它只是在黑洞中死去。

最後,我會非常感謝任何和所有可以幫助我理解套接字編程的教程/文章鏈接。

+0

請嘗試以下網頁上的示例代碼:https://msdn.microsoft.com/en-us/library/w89fhyex(v=vs.110).aspx。這些示例使用套接字,但您可以使用任何繼承套接字類的TCP類(如TCPListener,TCPClient)。我不喜歡初始化每種方法。這是不必要的,但是如果您沒有爲每封郵件打開新的連接,某些Microsoft庫方法無法正常工作。您發佈的示例代碼創建一個STATE對象,並將相同的STATE對象傳遞給每個事件(回調),以便代碼不打開和關閉連接。 STATE對象是一個傳入的參數。 – jdweng

+0

我確實已經閱讀過您提供的鏈接,因爲它僅僅是我上面發佈的鏈接的原始版本,所以我沒有將其包含在我的文章中。 你用混亂的方式表達了它(因爲我提到了初始化套接字,而不是方法),但是你是否說我每次發送郵件時都需要爲每條消息打開一個新套接字? 我的理解是否正確,你正在談論的STATE對象被轉換爲'IAsyncResult'並作爲參數傳遞給回調方法? – Amai

+1

在大多數情況下,您不需要爲每個連接打開新的套接字。您只需要小心一些庫方法會自動關閉連接,並且Microsoft很難檢測連接的打開和關閉時間,而不使用實際關閉連接的方法。 IAsyncResults.AsyncState是狀態對象。請參閱我之前發佈的網站上的示例。 – jdweng

回答

1

爲什麼acceptCallback會初始化一個新的套接字?

這就是BSD派生的套接字API的工作原理(並反映了TCP/IP網絡堆棧如何工作)。

您創建第一個套接字,其唯一作用是等待傳入連接:通過Listen(或變體)方法,然後通過Accept方法(或變體)建立連接。

其中返回另一個Socket實例,該實例將用於與一個客戶端通信套接字。

初始偵聽套接字繼續可用於新的傳入連接。

這反映了許多客戶端連接到服務器的模型。

可以想象Socket被兩個函數重載:1.列出並接受連接,2.代表已建立的連接。我認識到這一點,當Sun系統在80年代末用C語言編寫Sun OS時,所以我無法推薦這樣的建議無論如何:-)。


一旦建立了連接客戶端和服務器之間的操作 - 在套接字級別 - 對稱的,但它是想建立連接時,考慮服務器&客戶端角色非常有用。

+0

因此,我需要一個套接字來偵聽每個客戶端的新客戶端和額外套接字,我希望從中接收數據並將數據發送到每個客戶端(每個客戶端1個)? – Amai

+1

@Amai是的。 n個客戶的n + 1個插座。 – Richard

相關問題