2012-09-11 52 views
22

據我所知,我可以使用TCPListener和套接字創建一個服務器,那麼他們兩個之間有什麼區別?TCP監聽器和套接字之間的區別

插槽

private Socket MainSock; 
MainSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
MainSock.Bind(new IPEndPoint(IPAddress.Any, port)); 
MainSock.Listen(500); 
MainSock.BeginAccept(AcceptConnections, new Wrapper()); 

的TCPListener

Int32 port = 13000; 
    IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 
    TcpListener server = new TcpListener(localAddr, port); 
    server.Start(); 

我真的很困惑。他們兩個聽取聯繫,所以他們有什麼區別?

更新的代碼

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Net; 
using System.Net.Sockets; 
using System.Net.Security; 
using System.Security.Authentication; 
using System.Security.Cryptography.X509Certificates; 
using System.IO; 

public class Wrapper 
{ 
    public byte[] buffer; 
    public SslStream sslStream; 
    public object connector; 
} 

public class Sock 
{ 
    private Dictionary<string, byte> Connections; 
    public event Action<Wrapper> AnnounceNewConnection; 
    public event Action<Wrapper> AnnounceDisconnection; 
    public event Action<byte[], Wrapper> AnnounceReceive; 
    private Socket _sock; 

    private X509Certificate certificate = X509Certificate.CreateFromCertFile("exportedcertificate.cer"); 

    public Sock(int port) 
    { 
     try 
     { 
      Connections = new Dictionary<string, byte>(); 
      _sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      _sock.Bind(new IPEndPoint(IPAddress.Any, port)); 
      _sock.Listen(500); 
      _sock.BeginAccept(AcceptConnections, new Wrapper()); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
     } 
    } 

    private void AcceptConnections(IAsyncResult result) 
    { 
     Wrapper wr = (Wrapper)result.AsyncState; 
     try 
     { 
      wr.sslStream = new SslStream(new NetworkStream(_sock.EndAccept(result), true)); 
      wr.sslStream.BeginAuthenticateAsServer(certificate, AcceptAuthenticate, wr); 

      _sock.BeginAccept(AcceptConnections, new Wrapper()); 
     } 
     catch (Exception e) { Console.WriteLine(e); } 
    } 

    private void AcceptAuthenticate(IAsyncResult result) 
    { 
     Wrapper wr = (Wrapper)result.AsyncState; 
     try 
     { 
      wr.sslStream.EndAuthenticateAsServer(result); 
      if (wr.sslStream.IsAuthenticated == true) 
      { 
       AnnounceNewConnection.Invoke(wr); 
      } 
     } 
     catch (Exception e) { Console.WriteLine(e); } 
    } 

    private void ReceiveData(IAsyncResult result) 
    { 
     Wrapper wr = (Wrapper)result.AsyncState; 
     try 
     { 
      AnnounceReceive.Invoke(wr.buffer, wr); 
     } 
     catch (Exception e) { Console.WriteLine(e); AnnounceDisconnection.Invoke(wr); } 
    } 
} 

回答

11

他們只是不同的類,做同樣的事情,不同層次的寫入。在這種情況下,TCPListener無疑會調用非常類似於您的第一個基於Socket的代碼。它只是在那裏隱藏你的一些血淋淋的細節。

14

A TcpListener包裝一個插座,並且是服務器端模擬TcpClient(當然,它也包裹一個插座)。

TcpListener預先配置了TCP(與Socket可以用於UDP,純IP,非IP協議等相對),並在處理連接時爲您提供TcpClient。

如果你不確定是否需要一個套接字,並使用TCP - 我強烈建議從TcpListener/Client開始,因爲它是一個更容易使用的接口。

+0

我想使用SSL流,但IDK的我怎麼能使用.GetStream與插座類[第一示例] –

+0

@TorlanOther - 首先,你需要在插座的頂部流:系統。 Net.NetworkStream會給你。然後,在NetworkStream之上構建一個SslStream。 –

+0

所以你的意思是在AcceptConnections回調中,我製作了一個從AsyncResult獲取流的網絡流,然後我使用帶SSLStream的.GetStream? –

24

TcpListener是TCP通信的一個方便包裝。這允許您使用TcpClient進行接受的連接 - 雖然您可以接受套接字而不是客戶端來使用Socket而不是TcpClient。你可以用Socket做同樣的事情;但你必須處理一些TCP特定的(如SocketType.Stream, ProtocolType.Tcp)。 TCP是基於流的協議,並且TcpClient認識到讓你通過提供流TcpClient.GetStream()進行流通信。 Socket位於 更高的 不同的級別,並且需要支持許多不同的協議,例如不是基於流的UDP協議。

TcpClient.GetStream返回NetworkStream對象,它是適合於SslStream;所以,它應該比直接使用Socket少得多。使用TcpListenerTcpClient進行SSL通信的documentation for SslStream詳細信息。

+0

在我用來使用socket.BeginReceive的異步套接字類中,開始接收從客戶端發送的每條消息。但現在我用sslstream包裝我的套接字類以保證連接idk什麼是.BeginReceive在ssl –

+0

所以請我希望你能幫助我更新上面的主帖 –

+0

@TorlanOther如果你正在使用'SslStream',你想要使用'SslStream.BeginRead' –

0

我真的不回答這個問題,但你似乎喜歡TcpClient更好,因爲它具有GetStream(),您可以用SslStream使用,但你可以通過傳遞Socket作爲構造得到NetworkStreamSocketNetworkStream

NetworkStream myStream = new NetworkStream(mySocket);

+2

我不記得寫這個。 – robbie0630