贫道 發表於 2025-4-15 19:11:00

网络协议基本概念-TCP通信代码案例

<table>
<thead>
<tr>
<th>特性</th>
<th>TCP</th>
<th>UDP</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>面向连接</td>
<td>无连接</td>
</tr>
<tr>
<td></td>
<td>可靠(确保数据完整、按顺序到达)</td>
<td>不可靠(数据可能丢失、无序)</td>
</tr>
<tr>
<td></td>
<td>较慢(有连接和确认开销)</td>
<td>较快(无连接和确认开销)</td>
</tr>
<tr>
<td></td>
<td>字节流(无边界)</td>
<td>数据报(有明确边界)</td>
</tr>
<tr>
<td></td>
<td>文件传输、网页浏览、邮件传输等</td>
<td>实时通信、在线游戏、DNS 查询等</td>
</tr>
</tbody>
</table>
<p><strong>通俗的解释</strong></p>
<ul>
<li><strong>TCP</strong>:你打电话给朋友,先拨号建立连接,通话结束后挂断。通话过程中,如果对方没听到某句话,你可以重复说。</li>
<li><strong>UDP</strong>:你给朋友寄了一封明信片,不需要先打电话,直接寄出。明信片可能丢失,也可能迟到,但你不会知道。</li>
</ul>
<h2 id="下面给出一个基础的tcp通信代码案例"><em>下面给出一个基础的TCP通信代码案例</em></h2>
<h3 id="服务端代码"><strong>服务端代码</strong></h3>
<p>服务端代码的作用是监听客户端的连接请求,并与客户端进行通信。</p>
<h4 id="完整代码"><strong>完整代码</strong></h4>
<pre><code class="language-csharp">using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Server
{
    static void Main()
    {
      // 创建一个 TcpListener 对象,监听指定的 IP 地址和端口
      TcpListener listener = new TcpListener(IPAddress.Any, 8080);
      
      // 开始监听
      listener.Start();
      Console.WriteLine("Server started. Waiting for connection...");

      try
      {
            // 等待客户端连接
            TcpClient client = listener.AcceptTcpClient();
            Console.WriteLine("Client connected.");

            // 获取网络流,用于读写数据
            NetworkStream stream = client.GetStream();

            // 接收客户端发送的消息
            byte[] buffer = new byte;
            int bytesRead = stream.Read(buffer, 0, buffer.Length);
            string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
            Console.WriteLine("Received from client: " + message);

            // 向客户端发送响应
            byte[] response = Encoding.ASCII.GetBytes("Hello from server!");
            stream.Write(response, 0, response.Length);
            Console.WriteLine("Response sent to client.");
      }
      catch (Exception ex)
      {
            // 捕获异常并输出错误信息
            Console.WriteLine("Error: " + ex.Message);
      }
      finally
      {
            // 关闭客户端连接和监听器
            listener.Stop();
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
    }
}
</code></pre>
<h4 id="代码解析"><strong>代码解析</strong></h4>
<ol>
<li>
<p><strong>创建 <code>TcpListener</code> 对象</strong></p>
<pre><code class="language-csharp">TcpListener listener = new TcpListener(IPAddress.Any, 8080);
</code></pre>
<ul>
<li><code>TcpListener</code> 是服务端的核心类,用于监听客户端的连接请求。</li>
<li><code>IPAddress.Any</code> 表示监听所有网络接口上的连接。</li>
<li><code>8080</code> 是监听的端口号。</li>
</ul>
</li>
<li>
<p><strong>开始监听</strong></p>
<pre><code class="language-csharp">listener.Start();
Console.WriteLine("Server started. Waiting for connection...");
</code></pre>
<ul>
<li><code>Start()</code> 方法启动监听器,开始等待客户端连接。</li>
<li>此时服务端会输出 "Server started. Waiting for connection..."。</li>
</ul>
</li>
<li>
<p><strong>等待客户端连接</strong></p>
<pre><code class="language-csharp">TcpClient client = listener.AcceptTcpClient();
</code></pre>
<ul>
<li><code>AcceptTcpClient()</code> 方法会阻塞,直到有客户端连接到服务端。</li>
<li>连接成功后,返回一个 <code>TcpClient</code> 对象,表示与客户端的连接。</li>
</ul>
</li>
<li>
<p><strong>获取网络流</strong></p>
<pre><code class="language-csharp">NetworkStream stream = client.GetStream();
</code></pre>
<ul>
<li><code>GetStream()</code> 方法返回一个 <code>NetworkStream</code> 对象,用于在连接中读写数据。</li>
</ul>
</li>
<li>
<p><strong>接收客户端消息</strong></p>
<pre><code class="language-csharp">byte[] buffer = new byte;
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
</code></pre>
<ul>
<li><code>Read()</code> 方法从网络流中读取数据,返回实际读取的字节数。</li>
<li><code>Encoding.ASCII.GetString()</code> 将字节数组转换为字符串。</li>
<li>服务端会输出 "Received from client: " + 消息内容。</li>
</ul>
</li>
<li>
<p><strong>向客户端发送响应</strong></p>
<pre><code class="language-csharp">byte[] response = Encoding.ASCII.GetBytes("Hello from server!");
stream.Write(response, 0, response.Length);
</code></pre>
<ul>
<li><code>Encoding.ASCII.GetBytes()</code> 将字符串转换为字节数组。</li>
<li><code>Write()</code> 方法将字节数组写入网络流,发送给客户端。</li>
</ul>
</li>
<li>
<p><strong>异常处理</strong></p>
<pre><code class="language-csharp">catch (Exception ex)
{
    Console.WriteLine("Error: " + ex.Message);
}
</code></pre>
<ul>
<li>捕获异常并输出错误信息,方便调试。</li>
</ul>
</li>
<li>
<p><strong>关闭连接和监听器</strong></p>
<pre><code class="language-csharp">finally
{
    listener.Stop();
}
</code></pre>
<ul>
<li><code>Stop()</code> 方法停止监听器,关闭所有连接。</li>
</ul>
</li>
<li>
<p><strong>等待用户输入</strong></p>
<pre><code class="language-csharp">Console.WriteLine("Press any key to exit...");
Console.ReadKey();
</code></pre>
<ul>
<li>防止程序运行后立即退出,方便查看输出结果。</li>
</ul>
</li>
</ol>
<h3 id="客户端代码"><strong>客户端代码</strong></h3>
<p>客户端代码的作用是连接到服务端,并与服务端进行通信。</p>
<h4 id="完整代码-1"><strong>完整代码</strong></h4>
<pre><code class="language-csharp">using System;
using System.Net.Sockets;
using System.Text;

class Client
{
    static void Main()
    {
      // 创建一个 TcpClient 对象,用于连接到服务端
      TcpClient client = new TcpClient();
      
      try
      {
            // 连接到服务端
            client.Connect("127.0.0.1", 8080);
            Console.WriteLine("Connected to server.");

            // 获取网络流,用于读写数据
            NetworkStream stream = client.GetStream();

            // 向服务端发送消息
            byte[] message = Encoding.ASCII.GetBytes("Hello from client!");
            stream.Write(message, 0, message.Length);
            Console.WriteLine("Message sent to server.");

            // 接收服务端的响应
            byte[] buffer = new byte;
            int bytesRead = stream.Read(buffer, 0, buffer.Length);
            string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
            Console.WriteLine("Received from server: " + response);
      }
      catch (Exception ex)
      {
            // 捕获异常并输出错误信息
            Console.WriteLine("Error: " + ex.Message);
      }
      finally
      {
            // 关闭客户端连接
            client.Close();
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
    }
}
</code></pre>
<h4 id="代码解析-1"><strong>代码解析</strong></h4>
<ol>
<li>
<p><strong>创建 <code>TcpClient</code> 对象</strong></p>
<pre><code class="language-csharp">TcpClient client = new TcpClient();
</code></pre>
<ul>
<li><code>TcpClient</code> 是客户端的核心类,用于连接到服务端。</li>
</ul>
</li>
<li>
<p><strong>连接到服务端</strong></p>
<pre><code class="language-csharp">client.Connect("127.0.0.1", 8080);
</code></pre>
<ul>
<li><code>Connect()</code> 方法用于连接到指定的 IP 地址和端口。</li>
<li><code>127.0.0.1</code> 是本地回环地址,表示连接到本地服务端。</li>
<li><code>8080</code> 是服务端监听的端口号。</li>
</ul>
</li>
<li>
<p><strong>获取网络流</strong></p>
<pre><code class="language-csharp">NetworkStream stream = client.GetStream();
</code></pre>
<ul>
<li><code>GetStream()</code> 方法返回一个 <code>NetworkStream</code> 对象,用于在连接中读写数据。</li>
</ul>
</li>
<li>
<p><strong>向服务端发送消息</strong></p>
<pre><code class="language-csharp">byte[] message = Encoding.ASCII.GetBytes("Hello from client!");
stream.Write(message, 0, message.Length);
</code></pre>
<ul>
<li><code>Encoding.ASCII.GetBytes()</code> 将字符串转换为字节数组。</li>
<li><code>Write()</code> 方法将字节数组写入网络流,发送给服务端。</li>
</ul>
</li>
<li>
<p><strong>接收服务端响应</strong></p>
<pre><code class="language-csharp">byte[] buffer = new byte;
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
</code></pre>
<ul>
<li><code>Read()</code> 方法从网络流中读取数据,返回实际读取的字节数。</li>
<li><code>Encoding.ASCII.GetString()</code> 将字节数组转换为字符串。</li>
<li>客户端会输出 "Received from server: " + 响应内容。</li>
</ul>
</li>
<li>
<p><strong>异常处理</strong></p>
<pre><code class="language-csharp">catch (Exception ex)
{
    Console.WriteLine("Error: " + ex.Message);
}
</code></pre>
<ul>
<li>捕获异常并输出错误信息,方便调试。</li>
</ul>
</li>
<li>
<p><strong>关闭连接</strong></p>
<pre><code class="language-csharp">finally
{
    client.Close();
}
</code></pre>
<ul>
<li><code>Close()</code> 方法关闭客户端连接。</li>
</ul>
</li>
<li>
<p><strong>等待用户输入</strong></p>
<pre><code class="language-csharp">Console.WriteLine("Press any key to exit...");
Console.ReadKey();
</code></pre>
<ul>
<li>防止程序运行后立即退出,方便查看输出结果。</li>
</ul>
</li>
</ol>
<h3 id="运行步骤"><strong>运行步骤</strong></h3>
<ol>
<li>
<p><strong>先运行服务端代码</strong>:</p>
<ul>
<li>服务端会输出 "Server started. Waiting for connection..."。</li>
<li>服务端开始监听客户端连接。</li>
</ul>
</li>
<li>
<p><strong>再运行客户端代码</strong>:</p>
<ul>
<li>客户端会输出 "Connected to server."。</li>
<li>客户端发送消息 "Hello from client!" 到服务端。</li>
<li>服务端接收消息并输出 "Received from client: Hello from client!"。</li>
<li>服务端发送响应 "Hello from server!"。</li>
<li>客户端接收响应并输出 "Received from server: Hello from server!"。</li>
</ul>
</li>
<li>
<p><strong>查看结果</strong>:</p>
<ul>
<li>服务端和客户端的控制台窗口都会显示通信结果。</li>
<li>按任意键退出程序。</li>
</ul>
</li>
</ol>
<h3 id="总结"><strong>总结</strong></h3>
<p>通过以上详细解析,你可以快速理解服务端和客户端代码的逻辑。服务端负责监听连接并处理通信,客户端负责连接到服务端并发送/接收消息。掌握这些基础后,可以进一步学习更复杂的网络编程概念,如异步通信、多线程处理等。</p><br><br>
来源:https://www.cnblogs.com/structurer/p/18827307
頁: [1]
查看完整版本: 网络协议基本概念-TCP通信代码案例