设置TCP / IP客户端和服务器以通过网络进行通信

我正在尝试学习一些关于套接字编程的知识,我偶然发现了TcpListener和TcpClient,因为我读到它们对于初学者来说稍微容易一些。 我想要完成的基本要点是拥有一个可以在我的笔记本电脑和同一网络上的另一台笔记本电脑上运行的小型表格,以便它们能够进行通信,即相互发送一串文本。 有了这个,我希望能进一步发展:)

到目前为止,我已经使用msdn和互联网上的各种指南创建了客户端和服务器程序。 我可以让他们在一台笔记本电脑上运行时进行通信,但是当我将客户端移动到另一台笔记本电脑时,我无处可去。 我认为我的主要问题是我不太了解客户端如何找到服务器IP,因为我认为我可以硬编码,但当我再次回来时,我确信IP会发生变化。 有没有办法让两者以更动态的方式连接以包含不断变化的IP? 我目前的客户代码:

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

我当前的服务器代码:

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

你可能会说我对这是全新的,所以如果有更好的方法来实现这一点,我非常乐意学习! 在此先感谢任何帮助:)

我的解决方案得益于以下答案:

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

我不确定它是否是最好的解决方案但它运行良好所以谢谢你的答案:)

不太确定你的意思是“更有活力的方式来包含改变的IP”。 猜测你目前拥有的初学者:

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

您可以在同一台计算机上运行客户端和服务器,并使用本地环回IP地址:

 IPAddress.Parse("127.0.0.1") 

如果它们在不同的机器上运行,只需将127.0.0.1替换为服务器正在使用的任何IP地址(假设没有NAT或防火墙)。

如果您不想使用IP地址,则可以始终使用主机名(这些可能被视为更“动态”),但这需要适当配置的DNS设置(对于本地系统):

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

学习套接字编程真是太棒了。 我是网络库networkcomms.net的开发人员,所以如果你想学习自己的同时也想从工作示例中向后工作,请查看这个wpf聊天示例 。

如果您知道要连接的计算机的名称,那么您可以使用System.Net.DNS轻松找到其IP。

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

您认为正在使用的IP可能不是该arrays的0位置,因此请注意。