web-dev-qa-db-fra.com

Différence entre TCP Listener et Socket

Autant que je sache, je peux créer un serveur utilisant à la fois TCPListener et Socket. Quelle est la différence entre les deux?

Prise

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

Je suis vraiment confus. Ils écoutent tous les deux pour trouver des liens, alors quelle est la différence entre eux?

Code mis à jour

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); }
    }
}
25
Roman Ratskey

Ce sont juste des classes différentes qui font la même chose, écrites à différents niveaux. Sous le capot, TCPListener appelle sans doute quelque chose de très semblable à votre premier code basé sur Socket. C’est juste là pour vous cacher certains détails sanglants.

15
user207421

TcpListener est un wrapper pratique pour les communications TCP. Cela vous permet d'utiliser TcpClient pour les connexions acceptées - bien que vous puissiez accepter que les sockets au lieu des clients utilisent Socket au lieu de TcpClient. Vous pouvez faire la même chose avec Socket; mais vous devez traiter certaines des spécificités de TCP (comme SocketType.Stream, ProtocolType.Tcp). TCP est un protocole basé sur un flux et TcpClient reconnaît cela en vous permettant d'effectuer des communications en flux en fournissant un flux avec TcpClient.GetStream(). Socket est à plus haute niveau différent et doit prendre en charge de nombreux protocoles différents comme UDP qui ne sont pas basés sur le flux.

TcpClient.GetStream renvoie un objet NetworkStream qui convient pour SslStream; donc, cela devrait représenter beaucoup moins de travail que d’utiliser directement Socket. La documentation pour SslStream details utilisant TcpListener et TcpClient pour les communications SSL.

28
Peter Ritchie

Un TcpListener encapsule un socket et est l'analogue côté serveur du TcpClient (qui, bien sûr, encapsule également un socket).

TcpListener est préconfiguré avec TCP (par opposition au Socket, qui peut être utilisé avec UDP, IP pur, protocoles non-IP, etc.) et vous fournit un TcpClient lors du traitement d'une connexion.

Si vous n'êtes pas sûr d'avoir besoin d'un Socket et que vous utilisez TCP - Je vous suggère fortement de commencer par TcpListener/Client car c'est une interface beaucoup plus simple à utiliser.

15
Mark Brackett

Je ne réponds pas vraiment à la question, mais vous semblez mieux aimer TcpClient car il a GetStream() que vous pouvez utiliser avec un SslStream, mais vous pouvez obtenir un NetworkStream sur un Socket en passant le Socket à NetworkStream

c'est-à-dire NetworkStream myStream = new NetworkStream(mySocket);

0
robbie0630