2013-02-12 9 views
6

Sto cercando di imparare un po 'sulla programmazione dei socket e mi sono imbattuto in TcpListener e TcpClient da utilizzare mentre leggo, sono leggermente più facili per i principianti. L'essenza di base di ciò che voglio ottenere è di avere un piccolo modulo che può essere eseguito sul mio laptop e su un altro laptop sulla stessa rete e per essere in grado di comunicare, cioè inviare una stringa di testo tra loro. Spero di averlo ulteriormente sviluppato :)Configurare un client TCP/IP e un server per comunicare su una rete

Finora ho creato sia un client che un programma server utilizzando msdn e varie guide trovate su Internet. Posso convincerli a comunicare quando entrambi funzionano su un laptop, tuttavia quando sposto il client su un altro portatile non arrivo da nessuna parte. Penso che il mio problema principale è che non capisco abbastanza come il client trova l'IP dei server come penso che potrei scrivere un codice ma quando tornerò in un altro momento sono sicuro che l'IP sarà cambiato. C'è un modo per collegare i due in un modo più dinamico per comprendere l'IP che cambia? Il mio codice client corrente:

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

Il mio codice Server corrente:

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

Come si può probabilmente dire io sono nuovo di zecca per questo quindi se c'è un modo migliore per implementare questo io sono più che felice di imparare! Grazie per qualsiasi aiuto in anticipo :)

la mia soluzione grazie alle risposte qui sotto:

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

non sono sicuro se è la soluzione più pulita, ma si sta lavorando bene quindi grazie per le risposte :)

+1

Se stai cercando una revisione generale del codice, ti suggerirei di postare su [CodeReview.SE] (http://codereview.stackexchange.com/).Se stai cercando la risposta a una domanda specifica ("C'è un modo per collegare i due in un modo più dinamico per comprendere l'IP che cambia?"), Dovresti ridurre il codice solo nell'area che stai avendo problemi con. – Bobson

+0

Mi scuso Bobson Terrò i frammenti di codice più brevi e più rilevanti in futuro! Grazie per il consiglio :) –

risposta

1

Non sei proprio sicuro di cosa intendi per "modo più dinamico di comprendere l'ip mutevole". Facendo una supposizione per cominciare in cui è attualmente:

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

È possibile eseguire sia & client server sulla stessa macchina e utilizzare l'indirizzo di loopback IP locale:

IPAddress.Parse("127.0.0.1") 

Se sono in esecuzione su macchine diverse basta sostituire 127.0.0.1 con qualsiasi indirizzo IP utilizzato dal server (questo non presuppone NAT o firewall nel modo in cui).

Se non si desidera utilizzare gli indirizzi IP si può sempre usare nomi di host (questi potrebbero essere considerati più 'dinamica'), ma ciò richiederebbe una configurazione DNS opportunamente configurato (per i sistemi locali):

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

È fantastico imparare la programmazione dei socket. Sono lo sviluppatore di una libreria di rete, networkcomms.net, quindi dovresti anche voler tornare indietro da un esempio di lavoro e allo stesso tempo di imparare te stesso per favore controlla questo wpf chat example.

+0

Grazie mille, come ho visto nella mia modifica di op ho usato il nome host per ottenere l'IP e puntare a quello. Saluti per avermi indicato nella giusta direzione e darò sicuramente un'occhiata al tuo esempio di lavoro per saperne di più! –

1

Se si conosce il nome del computer a cui si desidera connettersi, è possibile trovare il relativo IP abbastanza facilmente con System.Net.DNS.

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

L'IP che pensi di utilizzare potrebbe non essere quello in posizione 0 di tale array, quindi fai attenzione.

+0

Grazie per il tuo aiuto Ho anche usato il tuo consiglio nella mia soluzione, penso di aver implementato un modo per assicurarmi di ottenere l'IP corretto da AddressList puoi vedere il mio tentativo nella mia modifica di op :) –

Problemi correlati