Подтвердить что ты не робот

Разница между приемником TCP и Socket

Насколько я знаю, я могу создать сервер, используя как TCPListener, так и 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();

Я действительно смущен. Они оба слушают подключения, так в чем же разница между ними?

Обновленный код

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

Ответ 1

Это просто разные классы, которые делают то же самое, написанные на разных уровнях. Под капотом TCPListener, несомненно, вызывает что-то очень похожее на ваш первый код на основе Socket. Это просто для того, чтобы скрыть вас от некоторых подробностей.

Ответ 2

TcpListener - удобная оболочка для связи TCP. Это позволяет использовать TcpClient для принятых соединений, хотя вы можете принимать сокеты вместо клиентов, чтобы использовать Socket вместо TcpClient. Вы можете сделать то же самое с Socket; но вам приходится иметь дело с некоторыми специфическими TCP-спецификациями (например, SocketType.Stream, ProtocolType.Tcp). TCP - это протокол, основанный на потоке, и TcpClient распознает, что позволяет передавать потоки через поток TcpClient.GetStream(). Socket находится на уровне более высокий и должен поддерживать множество разных протоколов, таких как UDP, которые не основаны на потоке.

TcpClient.GetStream возвращает объект NetworkStream, подходящий для SslStream; поэтому он должен работать гораздо меньше, чем непосредственно с помощью Socket. документация для SslStream, используя TcpListener и TcpClient для связи SSL.

Ответ 3

A TcpListener обертывает сокет и является аналогом на стороне сервера TcpClient (который также, конечно, обертывает сокет).

TcpListener предварительно сконфигурирован с помощью TCP (в отличие от Socket, который может использоваться с UDP, чистыми IP-протоколами, не-IP-протоколами и т.д.) и предоставляет TcpClient при обработке соединения.

Если вы не уверены, нужен ли вам Socket и используете TCP, я настоятельно рекомендую начать с TcpListener/Client, поскольку он гораздо проще в использовании.

Ответ 4

Я не отвечаю на этот вопрос, но вам кажется, что TcpClient лучше, потому что он имеет GetStream(), который вы можете использовать с SslStream, но вы можете получить NetworkStream из Socket путем передачи Socket в качестве конструктора в NetworkStream

то есть. NetworkStream myStream = new NetworkStream(mySocket);