2012-09-11 38 views
22

के बीच अंतर जहां तक ​​मुझे पता है कि मैं टीसीपी लिस्टर और सॉकेट दोनों का उपयोग कर एक सर्वर बना सकता हूं, तो उनमें से दोनों के बीच क्या अंतर है?टीसीपी श्रोता और सॉकेट

सॉकेट

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

वे विभिन्न स्तरों पर लिखा बस विभिन्न वर्गों है कि एक ही बात करते हैं, कर रहे हैं। हुड के तहत टीसीपी लिस्टनर निस्संदेह आपके पहले सॉकेट-आधारित कोड की तरह कुछ कहता है। यह सिर्फ कुछ गोरियों के विवरण से छिपाने के लिए है।

14

TcpListener सॉकेट लपेटता है, और TcpClient (जो भी, सॉकेट लपेटता है) के सर्वर-साइड एनालॉग है।

टीसीपी लिस्टनर टीसीपी के साथ पूर्वसंरचित है (सॉकेट के विपरीत, जिसका उपयोग यूडीपी, शुद्ध आईपी, गैर-आईपी प्रोटोकॉल इत्यादि के साथ किया जा सकता है) और कनेक्शन को संभालने पर आपको टीसीपी क्लाइंट देता है।

यदि आपको यकीन नहीं है कि आपको सॉकेट की आवश्यकता है, और टीसीपी का उपयोग कर रहे हैं - तो मैं दृढ़ता से टीसीपीलिस्टर/क्लाइंट के साथ शुरू करने का सुझाव देता हूं क्योंकि यह इंटरफ़ेस का उपयोग करना बहुत आसान है।

+0

मैं SSL स्ट्रीम उपयोग करना चाहते हैं लेकिन idk मैं कैसे सॉकेट वर्ग [प्रथम उदाहरण] –

+0

@TorlanOther साथ .GetStream इस्तेमाल कर सकते हैं - पहला, तो आपको स्ट्रीम सॉकेट की चोटी पर की जरूरत है: सिस्टम। Net.NetworkStream आपको वह देगा। फिर, नेटवर्कस्ट्रीम के शीर्ष पर एक एसएसएलस्ट्रीम बनाएं। –

+0

तो आपका मतलब AcceptConnections कॉलबैक पर है, मैं नेटवर्क स्ट्रीम करता हूं जो AsyncResult से स्ट्रीम प्राप्त करता है, तो मैं SSLStream के साथ .GetStream का उपयोग करता हूं? –

24

TcpListener टीसीपी संचार के लिए एक सुविधाजनक रैपर है। यह आपको स्वीकृत कनेक्शन के लिए TcpClient का उपयोग करने की अनुमति देता है - हालांकि आप TcpClient के बजाय Socket का उपयोग करने के बजाय ग्राहकों को सॉकेट स्वीकार कर सकते हैं। आप Socket के साथ एक ही काम कर सकते हैं; लेकिन आपको कुछ टीसीपी-विशिष्टताओं से निपटना होगा (जैसे SocketType.Stream, ProtocolType.Tcp)। टीसीपी एक स्ट्रीम-आधारित प्रोटोकॉल है और TcpClient पहचानता है कि TcpClient.GetStream() के साथ स्ट्रीम प्रदान करके आपको स्ट्रीम संचार करने की अनुमति मिलती है। Socket उच्च पर विभिन्न स्तर पर है और यूडीपी जैसे कई अलग-अलग प्रोटोकॉल का समर्थन करने की आवश्यकता है जो स्ट्रीम आधारित नहीं हैं।

TcpClient.GetStreamNetworkStream ऑब्जेक्ट देता है जो SslStream के लिए उपयुक्त है; इसलिए, यह सीधे Socket का उपयोग करने से बहुत कम काम होना चाहिए। एसएसएल संचार के लिए documentation for SslStream विवरण TcpListener और TcpClient का उपयोग कर विवरण।

+0

मेरी असीमित सॉकेट कक्षा में मैं सॉकेट का उपयोग करता था। ग्राहक से भेजे गए प्रत्येक संदेश को प्राप्त करने के लिए बेगीन रिसीव। लेकिन अब मैंने कनेक्शन आईडी को सुरक्षित करने के लिए एसएसएलस्ट्रीम के साथ अपनी सॉकेट क्लास को लपेटने के बाद एसएसएल –

+0

में बेगिनरसेसिव के बराबर क्या है, तो कृपया मैं चाहता हूं कि आप मुख्य पोस्ट –

+0

@TorlanOther में ऊपर दिए गए मेरे अपडेट किए गए कोड पर मेरी सहायता करें, यदि आप इसका उपयोग कर रहे हैं 'एसएसएलस्ट्रीम', आप हर बार उपरोक्त कोड पर इसका उपयोग करने का प्रयास करते समय 'SslStream.BeginRead' –

0

मैं वास्तव में सवाल नहीं का जवाब दे रहा हूँ, लेकिन आप क्योंकि यह GetStream() जो आपको एक SslStream साथ उपयोग कर सकते हैं TcpClient बेहतर पसंद करने लगते हैं, लेकिन आप Socket को एक निर्माता के रूप में पास करके एक NetworkStream एक Socket से बाहर निकल सकते NetworkStream

यानी NetworkStream myStream = new NetworkStream(mySocket);

+2

मुझे यह लिखना याद नहीं है। – robbie0630

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^