C#中简单Socket编程

C#中简单Socket编程

Socket分为面向连接的套接字(TCP套接字)和面向消息的套接字(UDP 套接字)。我们平时的网络编程是对Socket进行操作。

接下来,我用C#语言来进行简单的TCP通信和UDP通信。

一、TCP通信

新建项目SocketTest,首先添加TCP通信的客户端代码,如下:

byte[]data = new byte[1024];
            Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
            Console.WriteLine("Please write Server IPAdress:");
            string IPAdress = Console.ReadLine();
            Console.WriteLine();
            Console.Write("Please Write Server Port:");
            int nPort = Convert.ToInt32(Console.ReadLine());
            IPEndPoint IP = new IPEndPoint(IPAddress.Parse(IPAdress),nPort);
            try
            {
                ClientSocket.Connect(IP);
            }
            catch (SocketException e)
            {
                Console.WriteLine("Can Not Connet Server!");
                Console.WriteLine(e.ToString());
                return;
            }
            int nRetByte = ClientSocket.Receive(data);
            string strData = Encoding.ASCII.GetString(data,0, nRetByte);
            Console.WriteLine(strData);
            while (true)
            {
                string strInput = Console.ReadLine();
                if (strInput == "exit")
                    break;
                String strSay = " Client Say:"; 
                ClientSocket.Send(Encoding.ASCII.GetBytes(strSay + strInput));
                data = new byte[1024];
                nRetByte = ClientSocket.Receive(data);
                strData = Encoding.ASCII.GetString(data, 0, nRetByte);
                Console.WriteLine(strData);
            }
            Console.WriteLine("DisConnect From Server");
            ClientSocket.Shutdown(SocketShutdown.Both);
            ClientSocket.Close();

客户端套接字通信过程是:第一步:调用Socket类创建套接字。第二步:调用Connect()函数连接服务器。

TCP通信服务端代码如下:

 // 返回收到的字节数
            int nRetByte;
            byte[] data = new byte[1024];
            // IPEndPoint 将网络终结点表示为IP地址和端口号
            // IPAddress 提供网络协议IP地址
            IPEndPoint IPep = new IPEndPoint(IPAddress.Any,9050);
            // 实现 Berkeley套接字接口
            // AddressFamily:指定Socket类实例可以使用的寻址方案;
            // InterNetwork:IPV4版本的地址
            // SocketType:套集字类型;Stream:基于TCP的字节流类型
            // ProtocolType:协议的类型
            Socket newSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            // 使Socket与一个本地终结点相连
            newSocket.Bind(IPep);
            // 使Socket与处于监听状态
            newSocket.Listen(10);
            Console.WriteLine("Wait for a Client");
            // 为新建连接创建新的Socket
            Socket ClientSocket = newSocket.Accept();
            // RemoteEndPoint:获取远程终结点
            IPEndPoint ClientTip = (IPEndPoint)ClientSocket.RemoteEndPoint;
            Console.WriteLine("Connect with Client:"+ ClientTip.Address + "at Port:"+ ClientTip.Port);
            string strWelcome = "Welcome to Server,You Can Send Data To Server";
            // 获取ASCII字符集的编码
            // GetBytes将指定字符串中所有的字符编码为一个字节序列
            data = Encoding.ASCII.GetBytes(strWelcome);
            // 将数据发送到Socket
            ClientSocket.Send(data);
            while (true)
            {
                data = new byte[1024];
                // 从绑定的套接字接受数据,将数据存入接受缓冲区
                nRetByte = ClientSocket.Receive(data);
                Console.WriteLine("Receive Data from Client, Data Size is {0} Bit",nRetByte);
                if (nRetByte == 0)
                    break;
                Console.WriteLine(Encoding.ASCII.GetString(data,0,nRetByte));

                string strInput = Console.ReadLine();
                if (strInput == "exit")
                    break;

                String strSay = "Server Say:";
                ClientSocket.Send(Encoding.ASCII.GetBytes(strSay + strInput));
                Console.WriteLine(strInput);
            }
            Console.WriteLine("DisConnect from ClientAddress",ClientTip.Address);
            ClientSocket.Close();
            newSocket.Close();

TCP通信服务端的通信过程是:第一步调用Socket创建套接字。第二步:调用Bind()函数将套接字绑定到指定的IP地址和端口号。第三步:调用Listen()函数监听套接字。第四步:调用Accept()函数等待客户端连接。上述代码执行结果如下:

Snipaste_2024-07-09_23-13-02

这个测试使用本地回环地址127.0.0.1。

二、UDP通信

UDP通信是面向消息的通信方式。它具有快速不可靠的特点。UDP通信中客户端的过程:

第一步:创建套接字。第二步调用connect函数连接服务器(这一步是可选的,可以写可以不写)。具体代码如下:

 byte[] data = new byte[1024];
            string strInput, strData;
            // 定义一个源IP地址
            // Parse:IP地址字符串转换为IPAdress实例
            IPEndPoint ClientIP = new IPEndPoint(IPAddress.Parse("127.0.0.1"),9050);
            // 定义一个基于UDP协议的Socket
            Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
            string strWelcome = "Hello are you Here?";
            data = Encoding.ASCII.GetBytes(strWelcome);
            // 向服务器发送指定字节的数据
            ClientSocket.SendTo(data,data.Length, SocketFlags.None,ClientIP);
            IPEndPoint IPSender = new IPEndPoint(IPAddress.Any,0);
            EndPoint IPRemote = (EndPoint)IPSender;
            data = new byte[1024];
            int nRevByte = ClientSocket.ReceiveFrom(data,ref IPRemote);
            Console.WriteLine("Receive Data From Server:{0}", IPRemote.ToString());
            Console.WriteLine(Encoding.ASCII.GetString(data,0, nRevByte));
            while (true)
            {
                // 从标准输入流中读取下一行字符
                strInput = Console.ReadLine();
                if(strInput=="exit")
                    break;
                // 将从控制台中获取的数据发送到服务器端,并且接收服务器端发回的数据
                ClientSocket.SendTo(Encoding.ASCII.GetBytes(strInput), IPRemote);
                data = new byte[1024];
                nRevByte= ClientSocket.ReceiveFrom(data, ref IPRemote);
                strData= Encoding.ASCII.GetString(data,0, nRevByte);
                Console.WriteLine(strData);
            }
            Console.WriteLine("StopClient");
            ClientSocket.Close();

UDP通信服务器端通信过程:

第一步:创建套接字。第二步:将套接字绑定到指定IP地址和端口号。第三步:接收客户端的数据。具体代码如下:

int nRecvByte;
            byte[] data = new byte[1024];
            // 定义一个网络端点
            IPEndPoint IPAdress = new IPEndPoint(IPAddress.Any,9050);
            // 定义一个数据报类型的Socket
            // SocketType.Dgram:使用数据报协议
            // ProtocolType:UDP协议
            Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
            // Socket与本地的终端结点绑定
            ClientSocket.Bind(IPAdress);
            Console.WriteLine("Wait For a Client!");
            // 定义一个要发送的IP地址
            IPEndPoint Sender = new IPEndPoint(IPAddress.Any,0);
            EndPoint IPRemote = (IPEndPoint)Sender;
            // 接受数据报并存储源终结点
            nRecvByte = ClientSocket.ReceiveFrom(data,SocketFlags.None,ref IPRemote);
            Console.WriteLine("Message Receive From:{0}:", IPRemote.ToString());
            Console.WriteLine(Encoding.ASCII.GetString(data,0,nRecvByte));
            string strWelcome = "Welcome to My Test Server!";
            data = Encoding.ASCII.GetBytes(strWelcome);
            ClientSocket.SendTo(data,SocketFlags.None,IPRemote);
            while (true)
            {
                //接收客户端的数据并且发回 
                data = new byte[1024];
                nRecvByte = ClientSocket.ReceiveFrom(data,ref IPRemote);
                Console.WriteLine(Encoding.ASCII.GetString(data,0, nRecvByte));
                ClientSocket.SendTo(data,IPRemote);
            }

UDP通信效果如下:

Snipaste_2024-07-09_23-31-17
好了,今天就介绍到这里。欢迎大家一起交流。源码:SocketTest

上一篇:MMGPL: 多模态医学数据分析与图提示学习| 文献速递-基于深度学习的多模态数据分析与生存分析


下一篇:Visual Studio 如何确定文件生成的位置-也就是说下面所给的代码的基目录在binDebug下面