it-swarm.com.de

Unterschied zwischen TCP Hörer und Sockel

Soweit ich weiß, kann ich einen Server sowohl mit TCPListener als auch mit Socket erstellen. Was ist also der Unterschied zwischen den beiden?

Steckdose

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

Ich bin wirklich verwirrt. Die beiden warten auf Verbindungen, was ist der Unterschied zwischen ihnen?

Aktualisierter Code

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

Es sind einfach verschiedene Klassen, die dasselbe tun und auf verschiedenen Ebenen geschrieben werden. Unter der Haube nennt der TCPListener zweifellos so etwas wie Ihren ersten Socket-basierten Code. Es ist nur da, um Sie vor einigen blutigen Details zu verbergen.

15
user207421

TcpListener ist ein praktischer Wrapper für die Kommunikation mit TCP. Dadurch können Sie TcpClient für akzeptierte Verbindungen verwenden - obwohl Sie anstelle von Clients Sockets akzeptieren können, um Socket anstelle von TcpClient zu verwenden. Sie können dasselbe mit Socket tun. Sie müssen sich jedoch mit einigen der TCP-spezifischen Eigenschaften (wie SocketType.Stream, ProtocolType.Tcp) befassen. TCP ist ein Stream-basiertes Protokoll, und TcpClient erkennt dies, indem Sie Streams für die Kommunikation zulassen, indem Sie einen Stream mit TcpClient.GetStream() bereitstellen. Socket ist bei a höher verschiedene Ebenen und müssen viele verschiedene Protokolle wie UDP unterstützen, die nicht auf Streams basieren.

TcpClient.GetStream gibt ein NetworkStream-Objekt zurück, das für SslStream geeignet ist. Es sollte also viel weniger Arbeit sein, als Socket direkt zu verwenden. Die Dokumentation für SslStream details mit TcpListener und TcpClient für die SSL-Kommunikation.

28
Peter Ritchie

Ein TcpListener umschließt einen Socket und ist das serverseitige Analogon zum TcpClient (das natürlich auch einen Socket umschließt).

Der TcpListener ist mit TCP vorkonfiguriert (im Gegensatz zum Socket, der mit UDP, reiner IP, Nicht-IP-Protokollen usw. verwendet werden kann) und gibt Ihnen einen TcpClient für die Verbindungsabwicklung.

Wenn Sie sich nicht sicher sind, ob Sie ein Socket benötigen, und TCP verwenden, empfiehlt es sich dringend, mit TcpListener/Client zu beginnen, da diese Schnittstelle viel einfacher zu verwenden ist.

15
Mark Brackett

Ich beantworte die Frage nicht wirklich, aber Sie scheinen TcpClient besser zu mögen, weil sie GetStream() hat, die Sie mit einer SslStream verwenden können. Sie können jedoch eine NetworkStream aus einer Socket erhalten, indem Sie Socket als Konstruktor an NetworkStream übergeben

d.h. NetworkStream myStream = new NetworkStream(mySocket);

0
robbie0630