44

私の知る限り、TCPListener と Socket の両方を使用してサーバーを作成できますが、この 2 つの違いは何ですか?

ソケット

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

私は本当に混乱しています。この 2 つは接続をリッスンしますが、両者の違いは何ですか?

更新されたコード

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

4 に答える 4

40

TcpListenerTCP 通信の便利なラッパーです。これにより、受け入れられた接続に を使用できますが、の代わりTcpClientに使用するクライアントの代わりにソケットを受け入れることができます。;でも同じことができます。ただし、いくつかの TCP 固有のもの ( など) に対処する必要があります。TCP はストリームベースのプロトコルであり、ストリームに. より高いレベルにあり、ストリームベースではない UDP などのさまざまなプロトコルをサポートする必要があります。SocketTcpClientSocketSocketType.Stream, ProtocolType.TcpTcpClientTcpClient.GetStream()Socket

TcpClient.GetStreamNetworkStreamに適したオブジェクトを返しますSslStreamSocketしたがって、直接使用するよりも作業がはるかに少なくなるはずです。SslStreamの詳細については、SSL 通信を使用するTcpListenerためTcpClientのドキュメントを参照してください。

于 2012-09-12T00:45:51.070 に答える
24

それらは、同じことを行う異なるクラスであり、異なるレベルで記述されています。内部では、TCPListener は間違いなく、最初の Socket ベースのコードと非常によく似たものを呼び出します。それは、いくつかの悲惨な詳細からあなたを隠すためにそこにあるだけです.

于 2012-09-11T02:34:32.643 に答える
18

TcpListenerはソケットをラップし、サーバー側で TcpClient に類似しています(もちろん、ソケットもラップします)。

TcpListener は (UDP、純粋な IP、非 IP プロトコルなどで使用できるソケットとは対照的に) TCP で事前構成されており、接続を処理するときに TcpClient を提供します。

Socket が必要かどうかわからず、TCP を使用している場合は、TcpListener/Client から始めることを強くお勧めします。インターフェースを使用する方がはるかに簡単だからです。

于 2012-09-11T02:36:43.170 に答える
-1

私は実際に質問に答えているわけではありませんが、 で使用できるものをTcpClient持っているので、より好きなようですが、コンストラクターとしてを渡すことで a から取得できますGetStream()SslStreamNetworkStreamSocketSocketNetworkStream

すなわちNetworkStream myStream = new NetworkStream(mySocket);

于 2016-02-28T17:25:15.123 に答える