TCP侦听器和套接字之间的区别

时间:2012-09-11 02:31:50

标签: sockets tcp client serversocket tcplistener

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

4 个答案:

答案 0 :(得分:31)

TcpListener是TCP通信的便捷包装器。这允许您使用TcpClient来接受连接 - 尽管您可以接受套接字而不是客户端来使用Socket而不是TcpClient。你可以用Socket做同样的事情;但你必须处理一些特定于TCP的问题(如SocketType.Stream, ProtocolType.Tcp)。 TCP是一种基于流的协议,TcpClient通过提供带TcpClient.GetStream()的流来实现流通信,从而识别出这一点。 Socket处于更高的不同级别,需要支持许多不同的协议,如非基于流的UDP。

TcpClient.GetStream返回适合NetworkStream的{​​{1}}对象;所以,它应该比直接使用SslStream要少得多。 Socket详细信息使用TcpListenerTcpClient进行SSL通信。

答案 1 :(得分:16)

他们只是在不同的级别上做同样事情的不同类。在引擎盖下,TCPListener毫无疑问地调用了一些非常类似于你的第一个基于Socket的代码。它只是为了让你隐藏一些血腥的细节。

答案 2 :(得分:15)

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

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

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

答案 3 :(得分:0)

我并没有真正回答这个问题,但您似乎更喜欢TcpClient,因为它有GetStream()可以与SslStream一起使用,但您可以获得将NetworkStream作为构造函数传递给Socket

SocketNetworkStream {}

即。 NetworkStream myStream = new NetworkStream(mySocket);