2013-02-12 9 views
6

Soket programlaması hakkında biraz bilgi öğrenmeye çalışıyorum ve TcpListener ve TcpClient arasında tökezledim, yeni başlayanlar için biraz daha kolay olduklarını okudum. Yapmak istediğim şeyin temel jesti, dizüstü bilgisayarımda ve aynı ağdaki başka bir dizüstü bilgisayarda çalıştırılabilen ve iletişim kurabilmeleri için küçük bir forma sahip olmak, yani birbirleriyle bir metin dizesi göndermek. Bir kez bunu umarım daha fazla geliştiririm :)Bir ağ üzerinden iletişim kurmak için bir TCP/IP İstemcisi ve Sunucu Kurma

Şimdiye kadar bir istemci ve bir sunucu programı oluşturdum msdn ve internette bulunan çeşitli kılavuzları kullanarak. Her ikisi de bir dizüstü bilgisayarda çalışırken onları iletişim kurabilirim, ancak müşteriyi başka bir dizüstü bilgisayara taşıdığımda hiçbir yere varamayacağım. Sanırım asıl meselem, istemcinin sunucu kodlarını nasıl bulduğumu anlayamadığım kadar zor bir kod olduğunu düşündüğüm ama başka bir zamanda geri geldiğimde IP'nin değişeceğinden eminim. Değişen IP'yi kapsayacak şekilde daha dinamik bir şekilde bağlanmak için ikisini elde etmenin herhangi bir yolu var mı? Bulunduğum Müşteri kodu:

public void msg(string mesg) 
    { 
     lstProgress.Items.Add(">> " + mesg); 
    } 

    private void btnConnect_Click(object sender, EventArgs e) 
    { 
     string message = "Test"; 
     try 
     { 
      // Create a TcpClient. 
      // Note, for this client to work you need to have a TcpServer 
      // connected to the same address as specified by the server, port 
      // combination. 
      Int32 port = 1333; 
      TcpClient client = new TcpClient(<not sure>, port); //Unsure of IP to use. 

      // Translate the passed message into ASCII and store it as a Byte array. 
      Byte[] data = System.Text.Encoding.ASCII.GetBytes(message); 

      // Get a client stream for reading and writing. 
      // Stream stream = client.GetStream(); 

      NetworkStream stream = client.GetStream(); 

      // Send the message to the connected TcpServer. 
      stream.Write(data, 0, data.Length); 

      lstProgress.Items.Add(String.Format("Sent: {0}", message)); 

      // Receive the TcpServer.response. 

      // Buffer to store the response bytes. 
      data = new Byte[256]; 

      // String to store the response ASCII representation. 
      String responseData = String.Empty; 

      // Read the first batch of the TcpServer response bytes. 
      Int32 bytes = stream.Read(data, 0, data.Length); 
      responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
      lstProgress.Items.Add(String.Format("Received: {0}", responseData)); 

      // Close everything. 
      stream.Close(); 
      client.Close(); 
     } 
     catch (ArgumentNullException an) 
     { 
      lstProgress.Items.Add(String.Format("ArgumentNullException: {0}", an)); 
     } 
     catch (SocketException se) 
     { 
      lstProgress.Items.Add(String.Format("SocketException: {0}", se)); 
     } 
    } 

Bulunduğum Sunucu kodu:

private void Prog_Load(object sender, EventArgs e) 
    { 
     bw.WorkerSupportsCancellation = true; 
     bw.WorkerReportsProgress = true; 
     bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
     bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 

     if (bw.IsBusy != true) 
     { 
      bw.RunWorkerAsync(); 
     } 
    } 

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     lstProgress.Items.Add(e.UserState); 
    } 

    private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 

     if ((worker.CancellationPending == true)) 
     { 
      e.Cancel = true; 
     } 
     else 
     { 
      try 
      { 
       // Set the TcpListener on port 1333. 
       Int32 port = 1333; 
       //IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 
       TcpListener server = new TcpListener(IPAddress.Any, port); 

       // Start listening for client requests. 
       server.Start(); 

       // Buffer for reading data 
       Byte[] bytes = new Byte[256]; 
       String data = null; 

       // Enter the listening loop. 
       while (true) 
       { 
        bw.ReportProgress(0, "Waiting for a connection... "); 
        // Perform a blocking call to accept requests. 
        // You could also user server.AcceptSocket() here. 
        TcpClient client = server.AcceptTcpClient(); 
        bw.ReportProgress(0, "Connected!"); 

        data = null; 

        // Get a stream object for reading and writing 
        NetworkStream stream = client.GetStream(); 

        int i; 

        // Loop to receive all the data sent by the client. 
        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) 
        { 
         // Translate data bytes to a ASCII string. 
         data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
         bw.ReportProgress(0, String.Format("Received: {0}", data)); 

         // Process the data sent by the client. 
         data = String.Format("I Have Received Your Message: {0}", data); 

         byte[] mssg = System.Text.Encoding.ASCII.GetBytes(data); 

         // Send back a response. 
         stream.Write(mssg, 0, mssg.Length); 
         bw.ReportProgress(0, String.Format("Sent: {0}", data)); 
        } 

        // Shutdown and end connection 
        client.Close(); 
       } 
      } 
      catch (SocketException se) 
      { 
       bw.ReportProgress(0, String.Format("SocketException: {0}", se)); 
      } 
     } 
    } 

muhtemelen ben bu yüzden daha ÖS Bunu uygulamak için daha iyi bir yolu olup olmadığını bu yeni marka olduğumu söylemek gibi öğrenmek için mutlu! Aşağıdaki cevaplara önceden :) herhangi yardım için Teşekkür

Benim çözüm sayesinde:

private String IPAddressCheck() 
    { 
     var IPAddr = Dns.GetHostEntry("HostName"); 
     IPAddress ipString = null; 

     foreach (var IP in IPAddr.AddressList) 
     { 
      if(IPAddress.TryParse(IP.ToString(), out ipString) && IP.AddressFamily == AddressFamily.InterNetwork) 
      { 
       break; 
      } 
     } 
     return ipString.ToString(); 
    } 

    private void btnConnect_Click(object sender, EventArgs e) 
    { 
     string message = "Test"; 
     try 
     { 
      Int32 port = 1337; 
      string IPAddr = IPAddressCheck(); 
      TcpClient client = new TcpClient(IPAddr, port); 

Ben etkileyicisi çözüm olup olmadığından emin değilim ama iyi çalışıyor bu yüzden yanıtlar için teşekkür ederim

+1

Genel bir kod incelemesi arıyorsanız, bunun yerine [CodeReview.SE] (http://codereview.stackexchange.com/) adresine ileti göndermenizi öneririm.Belirli bir sorunun cevabını arıyorsanız ("Değişen IP'yi kapsayacak şekilde daha dinamik bir şekilde bağlanmak için ikisini elde etmenin herhangi bir yolu var mı?"), Kodu yalnızca bulunduğunuz alana indirmelisiniz. ile ilgili sorunlar. – Bobson

+0

Özür dilerim Bobson Kod snippet'larım gelecekte daha kısa ve daha alakalı tutmaya devam edeceğim! Tavsiye için teşekkürler :) –

cevap

1

'Değişen ipi kapsayacak daha dinamik bir yol' ile ne demek istediğinizden emin değilsiniz. bunlar farklı makineler üzerinde çalışıyorsa

IPAddress.Parse("127.0.0.1") 

:

TcpClient client = new TcpClient(<not sure>, port); //Unsure of IP to use. 

yerel geri döngü IP adresi aynı makinede hem istemci & sunucu çalıştırmak ve kullanabilirsiniz: şu anda sahip yeni başlayanlar için bir tahmin alarak Sadece sunucunun kullandığı IP adresi ile 127.0.0.1 değiştirin (bu şekilde NAT veya güvenlik duvarı olmadığını varsayar).

sen hep ana bilgisayar adlarını kullanabilirsiniz (bu daha 'dinamik' düşünülebilecek) ama bu (yerel sistemler için) uygun bir şekilde yapılandırılmış DNS ayarlarınızı gerektirecektir IP adreslerini kullanmak istemiyorsanız:

TcpClient client = new TcpClient("testMachine1", 1333); 

Soket programlamayı öğrenmek harika. Ben bir ağ kitaplığı geliştiricisiyim, networkcomms.net, bu yüzden aynı zamanda bir iş örneğinden geriye doğru çalışmak istiyorsanız, lütfen bu wpf chat example numaralı telefonu kullanın.

+0

Çok teşekkür ederim, benim düzenlemede görüldüğü gibi IP almak için ana bilgisayar adını kullandım ve buna işaret ettim. Beni doğru yönde işaret ettiğin için şereflendirdim ve biraz daha fazla şey öğrenmek için çalıştığın örneğe kesinlikle bir göz atacağım! –

1

Bağlanmak istediğiniz bilgisayarın adını biliyorsanız, System.Net.DNS ile IP adresini kolayca bulabilirsiniz.

var ip = System.Net.Dns.GetHostEntry("JacksLaptop"); 
string ipString = ip.AddressList[0].ToString(); 

Kullandığınızı düşündüğünüz IP, o dizinin 0 konumunda olmayabilir, bu nedenle buna dikkat edin.

+0

Yardımlarınız için teşekkür ederim Çözümümdeki tavsiyelerinizi de kullandım, sanırım AdresList'ten doğru IP'yi almamı sağlamaya çalıştığım bir yöntemi benim düzenlememde op girişimi görebiliyorum :) –