2012-09-11 23 views
22

Por lo que sé, puedo crear un servidor usando tanto TCPListener como Socket, entonces, ¿cuál es la diferencia entre los dos?Diferencia entre el Oyente TCP y el Socket

zócalo

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

estoy realmente confundido. Los dos escuchan las conexiones, entonces, ¿cuál es la diferencia entre ellos?

código actualizado

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

Respuesta

11

Son sólo diferentes clases que hacen lo mismo, escritos en diferentes niveles. Debajo del capó, el TCPListener sin duda llama algo muy parecido a su primer código basado en Socket. Está ahí para esconderte de algunos de los detalles sangrientos.

14

A TcpListener envuelve un zócalo, y es el lado del servidor análogo al TcpClient (que también, por supuesto, envuelve un zócalo).

El TcpListener está preconfigurado con TCP (a diferencia del Socket, que se puede usar con protocolos UDP, IP puro, no IP, etc.) y le proporciona un TcpClient cuando maneja una conexión.

Si no está seguro de si necesita un Socket y está usando TCP, le recomiendo comenzar con TcpListener/Client, ya que es una interfaz mucho más fácil de usar.

+0

quiero usar secuencia SSL, pero idk ¿Cómo podría utilizar .GetStream con la clase socket [primer ejemplo] –

+0

@TorlanOther - en primer lugar, necesita una corriente en la parte superior del zócalo: Sistema. Net.NetworkStream te dará eso. Luego, construye un SslStream encima de NetworkStream. –

+0

, ¿quiere decir que en la Devolución de llamada de AcceptConnections hago una transmisión de red que obtiene la transmisión de AsyncResult, y luego uso .GetStream con SSLStream? –

24

TcpListener es una envoltura conveniente para las comunicaciones TCP. Esto le permite usar TcpClient para conexiones aceptadas, aunque puede aceptar conectores en lugar de clientes para usar Socket en lugar de TcpClient. Puede hacer lo mismo con Socket; pero tiene que lidiar con algunos de los detalles de TCP (como SocketType.Stream, ProtocolType.Tcp). TCP es un protocolo basado en secuencias y TcpClient lo reconoce al permitirle transmitir comunicaciones al proporcionar una transmisión con TcpClient.GetStream(). Socket está en un nivel diferente y necesita admitir muchos protocolos diferentes, como UDP, que no se basan en secuencias.

TcpClient.GetStream devuelve un objeto NetworkStream que es adecuado para SslStream; por lo tanto, debería ser mucho menos trabajo que usar Socket directamente. El documentation for SslStream detalles usando TcpListener y TcpClient para comunicaciones SSL.

+0

en mi clase de socket asincrónico solía usar socket.BeginReceive para comenzar a recibir cada mensaje enviado por el cliente. pero ahora después envolví mi clase de socket con sslstream para asegurar la idk de conexión que es el equivalente de .BeginReceive en ssl –

+0

Así que por favor quiero que me ayuden en mi código actualizado arriba en la publicación principal –

+0

@TorlanOther Si está usando 'SslStream', querrías usar' SslStream.BeginRead' –

0

No estoy realmente responder a la pregunta, pero se parecen como TcpClient mejor porque tiene GetStream() que se puede utilizar con un SslStream, pero se puede obtener una NetworkStream cabo de un Socket pasando el Socket como constructor de NetworkStream

es decir NetworkStream myStream = new NetworkStream(mySocket);

+2

No recuerdo haber escrito esto. – robbie0630

Cuestiones relacionadas