Diferencia entre el receptor TCP y el Socket


Por lo que sé, puedo crear un servidor usando TcpListener y Socket, entonces, ¿cuál es la diferencia entre los dos?

Socket

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, así que, ¿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); }
    }
}
Author: Andrew Brooke, 2012-09-11

4 answers

Son solo diferentes clases que hacen lo mismo, escritas en diferentes niveles. Bajo el capó de TcpListener, sin duda, llama a algo muy parecido a su primer código basado en Sockets. Está ahí para esconderte de algunos de los detalles sangrientos.

 13
Author: user207421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-11 02:34:32

TcpListener es un envoltorio conveniente para las comunicaciones TCP. Esto le permite usar TcpClient para conexiones aceptadas although aunque puede aceptar sockets en lugar de clientes para usar Socket en lugar de TcpClient. Puedes hacer lo mismo con Socket; pero tienes que lidiar con algunos de los TCP-specifics (como SocketType.Stream, ProtocolType.Tcp). TCP es un protocolo basado en stream y TcpClient lo reconoce al permitirle hacer stream communications al proporcionar un stream con TcpClient.GetStream(). Socket está en un mayor diferente nivel y necesidades para soportar muchos protocolos diferentes como UDP que no están basados en stream.

TcpClient.GetStream devuelve un objeto NetworkStream que es adecuado para SslStream; por lo tanto, debería ser mucho menos trabajo que usar Socket directamente. La documentación para SslStream detalla el uso de TcpListener y TcpClient para comunicaciones SSL.

 25
Author: Peter Ritchie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-27 19:19:16

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

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

Si no está seguro de si necesita un Socket y está utilizando TCP, le sugiero encarecidamente que comience con TcpListener / Client, ya que es mucho más fácil de usar interfaz.

 14
Author: Mark Brackett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-11 02:36:43

Realmente no estoy respondiendo la pregunta, pero parece que te gusta TcpClient mejor porque tiene GetStream() que puedes usar con un SslStream, pero puedes obtener un NetworkStream de un Socket pasando el Socket como constructor a NetworkStream

Es decir, NetworkStream myStream = new NetworkStream(mySocket);

 0
Author: robbie0630,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-28 17:25:15