TCP Listener 和 Socket 的区别

问题描述 投票:0回答:5

据我所知,我可以同时使用 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());

TCP监听器

    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); }
    }
}
sockets tcp client serversocket tcplistener
5个回答
43
投票

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 通信。


25
投票

它们只是做同样事情的不同类,在不同级别编写。在底层,TCPListener 无疑会调用与您的第一个基于 Socket 的代码非常相似的东西。它只是为了让您隐藏一些血淋淋的细节。


21
投票

A TcpListener 包装了一个套接字,并且是 TcpClient 的服务器端模拟(当然,它也包装了一个套接字)。

TcpListener 预先配置了 TCP(与 Socket 不同,Socket 可以与 UDP、纯 IP、非 IP 协议等一起使用),并在处理连接时为您提供 TcpClient。

如果您不确定是否需要 Socket,并且正在使用 TCP - 我强烈建议从 TcpListener/Client 开始,因为它是一个更容易使用的接口。


0
投票

我并没有真正回答这个问题,但你似乎更喜欢

TcpClient
,因为它有
GetStream()
,你可以将其与
SslStream
一起使用,但你可以通过以下方式从
NetworkStream
中得到
Socket
Socket
作为构造函数传递给
NetworkStream

NetworkStream myStream = new NetworkStream(mySocket);


0
投票

我知道答案已经给出,但只是为了说明,当您查看

TcpListener
的源代码时,您可以看到它是套接字的包装器,并预先配置为使用 Tcp Stream。

© www.soinside.com 2019 - 2024. All rights reserved.