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