首页 > 编程笔记 > C#笔记 阅读:1

C#实现TCP通信详解(附带实例)

TCP(Transmission Control Protocol)即传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。

C# 中,TCP 程序设计是指利用 Socket 类、TcpClient 类和 TcpListener 类编写的网络通信程序,这 3 个类都位于 System.Net.Sockets 命名空间中。

利用 TCP 进行通信的两个应用程序是有主次之分的,一个称为服务器端程序,另一个称为客户端程序。

C# Socket类

Socket 类为网络通信提供了一套丰富的方法和属性,主要用于管理连接,实现 Berkeley 通信端套接字接口,同时它还定义了绑定、连接网络端点及传输数据所需的各种方法,提供处理端点连接传输等细节所需要的功能。TcpClient 和 UdpClinet 等类在内部使用该类。

Socket 类的常用属性及说明如下表所示。

表:Socket 类的常用属性及说明
属性 说明
AddressFamily 获取 Socket 的地址族
Available 获取已经从网络接收且可供读取的数据量
Connected 获取一个值,该值指示 Socket 是在上次 Send 还是 Receive 操作时连接到远程主机
Handle 获取 Socket 的操作系统句柄
LocalEndPoint 获取本地终结点
ProtocolType 获取 Socket 的协议类型
RemoteEndPoint 获取远程终结点
SendTimeout 获取或设置一个值,该值指定之后同步 Send 调用将超时的时间长度

Socket 类的常用方法及说明如下表所示。

表:Socket 类的常用方法及说明
方法 说明
Accept 为新建连接创建新的 Socket
BeginAccept 开始一个异步操作来接受一个传入的连接尝试
BeginConnect 开始一个对远程主机连接的异步请求
BeginDisconnect 开始异步请求从远程终结点断开连接
BeginReceive 开始从连接的 Socket 中异步接收数据
BeginSend 将数据异步发送到连接的 Socket
BeginSendFile 将文件异步发送到连接的 Socket
BeginSendTo 向特定远程主机异步发送数据
Close 关闭 Socket 连接并释放所有关联的资源
Connect 建立与远程主机的连接
Disconnect 关闭套接字连接,并允许重用套接字
EndAccept 异步接收传入的连接尝试
EndConnect 结束挂起的异步连接请求
EndDisconnect 结束挂起的异步断开连接请求
EndReceive 结束挂起的异步读取
EndSend 结束挂起的异步发送
EndSendFile 结束文件的挂起异步发送
EndSendTo 结束挂起的、向指定位置进行的异步发送
Listen 将 Socket 置于侦听状态
Receive 接收来自绑定的 Socket 的数据
Send 将数据发送到连接的 Socket
SendFile 将文件和可选数据异步发送到连接的Socket
SendTo 将数据发送到特定的终结点
Shutdown 禁用某 Socket上的发送和接收

C# TcpClient类和TcpListener类

TcpClient 类用于在同步阻止模式下通过网络来连接、发送和接收流数据。为了使 TcpClient连 接并交换数据,TcpListener 实例或 Socket 实例必须侦听是否有传入的连接请求。

可以使用下面两种方法之一连接到该侦听器:
TcpListener 类用于在同步阻止模式下侦听和接收传入的连接请求。可使用 TcpClient 类或 Socket 类来连接 TcpListener,并且可以使用 IPEndPoint、本地 IP 地址及端口号或者仅使用端口号来创建 TcpListener 实例对象。

TcpClient 类的常用属性、方法及说明如下表所示。

表:TcpClient类的常用属性、方法及说明

属性及方法 说明
Available 属性 获取已经从网络接收且可供读取的数据量
Client 属性 获取或设置基础Socket
Connected 属性 获取一个值,该值指示TcpClient的基础Socket是否已连接到远程主机
ReceiveBufferSize 属性 获取或设置接收缓冲区的大小
ReceiveTimeout 属性 获取或设置在初始化一个读取操作后 TcpClient 等待接收数据的时间量
SendBufferSize 属性 获取或设置发送缓冲区的大小
SendTimeout 属性 获取或设置TcpClient等待发送操作成功完成的时间量
BeginConnect 方法 开始一个对远程主机连接的异步请求
Close 方法 释放此TcpClient实例,而不关闭基础连接
Connect 方法 使用指定的主机名和端口号将客户端连接到TCP主机
EndConnect 方法 异步接收传入的连接尝试
GetStream 方法 返回用于发送和接收数据的NetworkStream

TcpListener 类的常用属性、方法及说明如下表所示。

表:TcpListener 类的常用属性、方法及说明
属性及方法 说明
LocalEndpoint 属性 获取当前 TcpListener 的基础 EndPoint
Server 属性 获取基础网络 Socket
AcceptSocket/AcceptTcpClient 方法 接收挂起的连接请求
BeginAcceptSocket/BeginAcceptTcpClient 方法 开始一个异步操作来接收一个传入的连接尝试
EndAcceptSocket 方法 异步接收传入的连接尝试,并创建新的 Socket 来处理远程主机通信
EndAcceptTcpClient 方法 异步接收传入的连接尝试,并创建新的 TcpClient 来处理远程主机通信
Start 方法 开始侦听传入的连接请求
Stop 方法 关闭侦听器

C# TCP网络程序实例

创建服务器端项目 Server,首先在 Main 方法中创建 TCP 连接对象;然后监听客户端接入,并读取接入的客户端 IP 地址和传入的消息;最后向接入的客户端发送一条信息,代码如下:
namespace Server
{
    class Program
    {
        static void Main()
        {
            int port = 888; //端口
            TcpClient tcpclient; //创建TCP连接对象
            IPAddress[] serverIP = Dns.GetHostAddresses("127.0.0.1"); //定义IP地址
            IPAddress localAddress = serverIP[0]; //IP地址
            TcpListener tcpListener = new TcpListener(localAddress, port); //监听套接字
            tcpListener.Start(); //开始监听
            Console.WriteLine("服务器启动成功,等待用户接入…"); //输出消息
            while (true)
            {
                try
                {
                    //每接收一个客户端则生成一个TcpClient
                    tcpclient = tcpListener.AcceptTcpClient();
                    NetworkStream networkStream = tcpclient.GetStream(); //获取网络数据流
                    //定义流数据读取对象
                    BinaryReader reader = new BinaryReader(networkStream);
                    //定义流数据写入对象
                    BinaryWriter writer = new BinaryWriter(networkStream);
                    while (true)
                    {
                        try
                        {
                            string strReader = reader.ReadString(); //接收消息
                            //截取客户端消息
                            string[] strReaders = strReader.Split(new char[] { ',' });
                            //输出接收的客户端IP地址
                            Console.WriteLine("有客户端接入,客户IP:" + strReaders[0]);
                            //输出接收的消息
                            Console.WriteLine("来自客户端的消息:" + strReaders[1]);
                            string strWriter = "我是服务器,欢迎光临"; //定义服务器端要写入的消息
                            writer.Write(strWriter); //向对方发送消息
                        }
                        catch
                        {
                            break;
                        }
                    }
                }
                catch
                {
                    break;
                }
            }
        }
    }
}

创建客户端项目 Client,首先在 Main 方法中创建 TCP 连接对象,以指定的地址和端口连接服务器;然后向服务器端发送数据和接收服务器端传输的数据。代码如下:
namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个TcpClient对象,自动分配主机IP地址和端口号
            TcpClient tcpclient = new TcpClient();
            //连接服务器,其IP和端口号为127.0.0.1和888
            tcpclient.Connect("127.0.0.1", 888);
            if (tcpclient != null) //判断是否连接成功
            {
                Console.WriteLine("连接服务器成功");
                NetworkStream networkStream = tcpclient.GetStream(); //获取数据流
                BinaryReader reader = new BinaryReader(networkStream); //定义流数据读取对象
                BinaryWriter writer = new BinaryWriter(networkStream); //定义流数据写入对象
                string localip = "127.0.0.1"; //存储本机IP,默认值为127.0.0.1
                IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); //获取所有IP地址
                foreach (IPAddress ip in ips)
                {
                    if (!ip.IsIPv6SiteLocal) //如果不是IPv6地址
                        localip = ip.ToString(); //获取本机IP地址
                }
                writer.Write(localip + ",你好服务器,我是客户端"); //向服务器发送消息
                while (true)
                {
                    try
                    {
                        string strReader = reader.ReadString(); //接收服务器发送的数据
                        if (strReader != null)
                        {
                            //输出接收的服务器消息
                            Console.WriteLine("来自服务器的消息:" + strReader);
                        }
                    }
                    catch
                    {
                        break; //接收过程中如果出现异常,则退出循环
                    }
                }
            }
            Console.WriteLine("连接服务器失败");
        }
    }
}
首先运行服务器端,然后运行客户端,运行客户端后的服务器端效果为:

服务器启动成功,等待用户接入…
有客户端接入,客户IP:192.168.1.150
来自客户端的消息:你好服务器,我是客户端


客户端运行效果为:

连接服务器成功
来自服务器的消息:我是服务器,欢迎光临

相关文章