2012-09-11 79 views
22

据我所知,我可以使用TCPListener和套接字创建一个服务器,那么他们两个之间有什么区别?TCP监听器和套接字之间的区别

插槽

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

回答

11

他们只是不同的类,做同样的事情,不同层次的写入。在这种情况下,TCPListener无疑会调用非常类似于您的第一个基于Socket的代码。它只是在那里隐藏你的一些血淋淋的细节。

14

A TcpListener包装一个插座,并且是服务器端模拟TcpClient(当然,它也包裹一个插座)。

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

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

+0

我想使用SSL流,但IDK的我怎么能使用.GetStream与插座类[第一示例] –

+0

@TorlanOther - 首先,你需要在插座的顶部流:系统。 Net.NetworkStream会给你。然后,在NetworkStream之上构建一个SslStream。 –

+0

所以你的意思是在AcceptConnections回调中,我制作了一个从AsyncResult获取流的网络流,然后我使用带SSLStream的.GetStream? –

24

TcpListener是TCP通信的一个方便包装。这允许您使用TcpClient进行接受的连接 - 虽然您可以接受套接字而不是客户端来使用Socket而不是TcpClient。你可以用Socket做同样的事情;但你必须处理一些TCP特定的(如SocketType.Stream, ProtocolType.Tcp)。 TCP是基于流的协议,并且TcpClient认识到让你通过提供流TcpClient.GetStream()进行流通信。 Socket位于 更高的 不同的级别,并且需要支持许多不同的协议,例如不是基于流的UDP协议。

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

+0

在我用来使用socket.BeginReceive的异步套接字类中,开始接收从客户端发送的每条消息。但现在我用sslstream包装我的套接字类以保证连接idk什么是.BeginReceive在ssl –

+0

所以请我希望你能帮助我更新上面的主帖 –

+0

@TorlanOther如果你正在使用'SslStream',你想要使用'SslStream.BeginRead' –

0

我真的不回答这个问题,但你似乎喜欢TcpClient更好,因为它具有GetStream(),您可以用SslStream使用,但你可以通过传递Socket作为构造得到NetworkStreamSocketNetworkStream

NetworkStream myStream = new NetworkStream(mySocket);

+2

我不记得写这个。 – robbie0630