2012-09-11 56 views
22

Theo như tôi biết tôi có thể tạo một máy chủ sử dụng cả TCPListener và Socket, vì vậy sự khác biệt giữa hai người trong số họ là gì?Sự khác biệt giữa TCP Listener và Socket

Ổ cắm

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(); 

Tôi thực sự bối rối. Hai người trong số họ lắng nghe các kết nối, vậy sự khác biệt giữa chúng là gì?

Mã Cập nhật

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); } 
    } 
} 

Trả lời

11

Họ chỉ lớp học khác nhau mà làm điều tương tự, được viết ở mức độ khác nhau. Dưới mui xe, TCPListener chắc chắn gọi một cái gì đó rất giống như mã dựa trên Socket đầu tiên của bạn. Nó chỉ ở đó để che giấu bạn khỏi một số chi tiết đẫm máu.

14

A TcpListener kết thúc tốt nhất ổ cắm và tương tự phía máy chủ với TcpClient (tất nhiên, cũng kết thúc một ổ cắm).

TcpListener được cấu hình sẵn với TCP (trái với Socket, có thể được sử dụng với UDP, IP thuần, giao thức không phải IP, vv) và cung cấp cho bạn TcpClient khi xử lý kết nối.

Nếu bạn không chắc chắn liệu mình có cần Socket hay không và đang sử dụng TCP - Tôi khuyên bạn nên bắt đầu với TcpListener/Client vì giao diện dễ sử dụng hơn nhiều.

+0

tôi muốn sử dụng suối SSL nhưng idk làm thế nào tôi có thể sử dụng .GetStream với lớp ổ cắm [First Ví dụ] –

+0

@TorlanOther - đầu tiên, bạn cần một dòng suối trên đầu trang của các ổ cắm: System. Net.NetworkStream sẽ cung cấp cho bạn điều đó. Sau đó, xây dựng một SslStream trên đầu trang của NetworkStream. –

+0

vì vậy bạn có nghĩa là trên AcceptConnections gọi lại tôi làm cho một dòng mạng được dòng từ AsyncResult, sau đó tôi sử dụng .GetStream với SSLStream? –

24

TcpListener là trình bao bọc tiện lợi cho giao tiếp TCP. Điều này cho phép bạn sử dụng TcpClient cho các kết nối được chấp nhận - mặc dù bạn có thể chấp nhận ổ cắm thay vì khách hàng sử dụng Socket thay vì TcpClient. Bạn có thể làm điều tương tự với Socket; nhưng bạn phải đối phó với một số chi tiết cụ thể của TCP (như SocketType.Stream, ProtocolType.Tcp). TCP là một giao thức dựa trên luồng và TcpClient nhận ra rằng bằng cách cho phép bạn truyền thông luồng bằng cách cung cấp luồng với TcpClient.GetStream(). Socket ở mức cao hơn cấp độ khác nhau và cần hỗ trợ nhiều giao thức khác nhau như UDP không dựa trên luồng.

TcpClient.GetStream trả về đối tượng NetworkStream phù hợp cho SslStream; vì vậy, nó sẽ ít hơn nhiều so với việc sử dụng trực tiếp Socket. Chi tiết documentation for SslStream sử dụng TcpListenerTcpClient để liên lạc SSL.

+0

trong lớp không đồng bộ của tôi socket tôi được sử dụng để sử dụng socket.BeginReceive để bắt đầu nhận được tất cả các tin nhắn được gửi từ khách hàng. nhưng bây giờ sau khi tôi bọc lớp socket của tôi với sslstream để bảo đảm idk kết nối tương đương với .BeginReceive trong ssl –

+0

Vì vậy, xin vui lòng tôi muốn bạn giúp tôi trên mã cập nhật của tôi ở trên trong bài chính –

+0

@TorlanOther Nếu bạn đang sử dụng 'SslStream', bạn muốn sử dụng' SslStream.BeginRead' –

0

Tôi không thực sự trả lời các câu hỏi, nhưng bạn dường như muốn TcpClient tốt hơn bởi vì nó có GetStream() mà bạn có thể sử dụng với một SslStream, nhưng bạn có thể có được một NetworkStream ra khỏi một Socket bằng cách truyền Socket như một constructor để NetworkStream

tức NetworkStream myStream = new NetworkStream(mySocket);

+2

Tôi không nhớ đã viết điều này. – robbie0630

Các vấn đề liên quan