私の知る限り、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); }
}
}
それらは、異なるレベルで書かれた同じことを行う異なるクラスです。内部では、TCPListenerは間違いなく最初のSocketベースのコードのようなものを呼び出します。それは、いくつかの厄介な詳細からあなたを隠すためだけにあります。
TcpListener
は、TCP通信の便利なラッパーです。これにより、受け入れられた接続にTcpClient
を使用できます。ただし、Socket
の代わりにTcpClient
を使用するために、クライアントの代わりにソケットを受け入れることができます。 Socket
でも同じことができます。ただし、TCP固有のいくつか(_SocketType.Stream, ProtocolType.Tcp
_など)を処理する必要があります。 TCPはストリームベースのプロトコルであり、TcpClient
は、TcpClient.GetStream()
でストリームを提供することにより、ストリーム通信を可能にすることでそれを認識します。 Socket
は より高い 異なるレベルであり、ストリームベースではないUDPなどの多くの異なるプロトコルをサポートする必要があります。
_TcpClient.GetStream
_は、NetworkStream
に適したSslStream
オブジェクトを返します。そのため、Socket
を直接使用するよりも作業がはるかに少なくなります。 SslStreamのドキュメント SSL通信にTcpListener
およびTcpClient
を使用した詳細。
TcpListener はソケットをラップし、 TcpClient (もちろん、ソケットをラップする)のサーバー側の類似物です。
TcpListenerは、TCP(ソケットとは対照的に、UDP、純粋なIP、非IPプロトコルなどで使用できます)と設定されており、接続を処理するときにTcpClientを提供します。
ソケットが必要かどうかわからず、TCP-インターフェイスを使用する方がはるかに簡単であるため、TcpListener/Clientから開始することを強くお勧めします。
私は質問に本当に答えていませんが、TcpClient
で使用できるGetStream()
があるため、SslStream
の方が好きなようですが、NetworkStream
をコンストラクタとして渡すことでSocket
からSocket
を取得できますNetworkStream
へ
つまり、NetworkStream myStream = new NetworkStream(mySocket);