2013-02-12 30 views
6

Tôi đang cố gắng tìm hiểu một chút về lập trình socket và tôi đã tình cờ gặp TcpListener và TcpClient để sử dụng khi tôi đọc chúng dễ dàng hơn cho người mới bắt đầu. Câu chuyện cơ bản về những gì tôi muốn hoàn thành là có một biểu mẫu nhỏ có thể chạy trên máy tính xách tay của tôi và một máy tính xách tay khác trên cùng một mạng và để họ có thể giao tiếp tức là gửi một chuỗi văn bản cho nhau. Khi tôi có điều này, tôi hy vọng sẽ phát triển thêm nữa :)Thiết lập Máy khách và Máy chủ TCP/IP để liên lạc qua mạng

Cho đến giờ tôi đã tạo cả chương trình Máy khách và Máy chủ bằng cách sử dụng msdn và các hướng dẫn khác nhau trên internet. Tôi có thể làm cho họ giao tiếp khi cả hai chạy trên một máy tính xách tay tuy nhiên khi tôi di chuyển máy khách đến một máy tính xách tay khác, tôi nhận được hư không. Tôi nghĩ vấn đề chính của tôi là tôi không hiểu làm thế nào khách hàng tìm thấy IP của máy chủ vì tôi nghĩ rằng tôi có thể mã hóa nó nhưng khi tôi quay lại vào lúc khác, tôi chắc chắn rằng IP sẽ thay đổi. Có cách nào để có được hai kết nối một cách năng động hơn để bao gồm IP thay đổi? Khách hàng mã hiện tại của tôi:

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

mã máy chủ hiện tại của tôi:

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

Như bạn có lẽ có thể nói với tôi hoàn toàn mới này vì vậy nếu có một cách tốt hơn để thực hiện điều này tôi hơn hạnh phúc để tìm hiểu! Nhờ sự giúp đỡ trước :)

Giải pháp của tôi nhờ vào các câu trả lời dưới đây:

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

Tôi không chắc chắn nếu nó là giải pháp thú vị nhất nhưng nó đang làm việc cũng rất cảm ơn bạn đã trả lời :)

+1

Nếu bạn đang tìm kiếm một đánh giá chung về mã, tôi khuyên bạn nên đăng bài lên [CodeReview.SE] (http://codereview.stackexchange.com/) để thay thế.Nếu bạn đang tìm câu trả lời cho một câu hỏi cụ thể ("Có cách nào để kết nối hai cách kết nối một cách năng động hơn để bao gồm IP thay đổi không?"), Bạn nên giảm mã xuống chỉ là khu vực bạn đang gặp vấn đề với. – Bobson

+0

Xin lỗi Bobson Tôi sẽ giữ đoạn mã ngắn hơn và phù hợp hơn trong tương lai! Cảm ơn những lời khuyên :) –

Trả lời

1

Không hoàn toàn chắc chắn ý bạn là gì theo 'cách năng động hơn để bao gồm ip thay đổi'. Tham gia một dự đoán cho người mới bắt đầu mà bạn đang có:

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

Bạn có thể chạy cả hai khách hàng & máy chủ trên cùng một máy và sử dụng các địa phương địa chỉ loopback IP:

IPAddress.Parse("127.0.0.1") 

Nếu họ đang chạy trên các máy khác nhau chỉ cần thay thế 127.0.0.1 bằng bất kỳ địa chỉ IP nào mà máy chủ đang sử dụng (điều này giả định không có NAT hoặc tường lửa nào).

Nếu bạn không muốn sử dụng địa chỉ IP mà bạn luôn luôn có thể sử dụng hostname (những có thể được coi thêm 'năng động') nhưng điều này sẽ đòi hỏi một thiết lập cấu hình phù hợp DNS (cho các hệ thống địa phương):

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

Thật tuyệt vời khi học lập trình socket. Tôi là nhà phát triển của một thư viện mạng, networkcomms.net, vì vậy bạn cũng nên muốn làm việc ngược trở lại từ một ví dụ làm việc cùng một lúc khi tự học, vui lòng thanh toán số wpf chat example này.

+0

Cảm ơn bạn rất nhiều, như đã thấy trong chỉnh sửa của tôi để op tôi đã sử dụng tên máy chủ để có được IP và trỏ đến đó. Chúc mừng vì đã chỉ cho tôi đúng hướng và tôi chắc chắn sẽ xem xét ví dụ làm việc của bạn để tìm hiểu thêm! –

1

Nếu bạn biết tên máy tính bạn muốn kết nối, bạn có thể tìm thấy IP của nó khá dễ dàng với System.Net.DNS.

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

IP bạn cho rằng bạn đang sử dụng có thể không phải là địa điểm ở vị trí 0 của mảng đó nên hãy chú ý.

+0

Cảm ơn sự giúp đỡ của bạn Tôi cũng đã sử dụng lời khuyên của bạn trong giải pháp của tôi, tôi nghĩ rằng tôi đã thực hiện một cách để đảm bảo rằng tôi nhận được IP chính xác từ AddressList bạn có thể thấy nỗ lực của tôi trong chỉnh sửa của tôi để op :) –

Các vấn đề liên quan