C# Socket realizes UDP protocol communication

The original address of this article is: http://greatverve.cnblogs.com/archive/2011/06/26/Socket-UDP.html

It took a little time today to use C# Socket to verify the UDP communication, laying the foundation for the next special use of UDP as a distributed communication simulation system. As we all know, UDP is the user datagram protocol, which is the fourth layer of the Internet reference model-the transport layer. At the same layer as the TCP protocol, both provide information transmission services, but the biggest difference from TCP is that it is a connectionless and unreliable information transmission.

What is unreliable without connection? To put it bluntly, when sending data, just throw the UDP packet to the network and it will be done. If it is received or not, it will be ignored; when receiving data, if there is a local UDP packet, just follow the order. Receive all, and see who sent it after receiving it. Compared with TCP, a series of processes such as handshake connection establishment, connection maintenance, and connection release are omitted, so it has the advantages of small resource consumption and fast processing speed.

Okay, I said a lot of nonsense, and I started to talk about how to use Socket in C# for UDP communication. TCP and UDP applications can be programmed through the TCPClient, TCPListener and UDPClient classes, and these protocol classes are also based on the System.Net.Sockets.Socket class, and do not need to worry about the details of data transmission. But in order to better understand Socket programming, here we still use the Socket class for UDP communication programming.

 In UDP applications, there is no longer a real server and a client in the strict sense. The endpoints are all equal, so only one program is required to communicate.

The key part of the code and description are given below:

1. Key global variables

private IPEndPoint ipLocalPoint; //本地IP和端口号
private EndPoint RemotePoint;  //远程网络地址标识
private Socket mySocket;  //Socket
private bool RunningFlag = false;  //接受线程运行标志

2. How to get local IP
private string getIPAddress()  
 {  
     // 获得本机局域网IP地址  
     IPAddress[] AddressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;  
     if (AddressList.Length < 1)  
     {  
         return "";  
     }  
     return AddressList[0].ToString();  
 }  

3. Effective verification of IP and port number
private int getValidPort(string port)  
    {  
        int lport;  
        //测试端口号是否有效  
        try  
        {  
            //是否为空  
            if (port == "")  
            {  
                throw new ArgumentException(  
                    "端口号无效,不能启动UDP");  
            }  
            lport = System.Convert.ToInt32(port);  
        }  
        catch (Exception e)  
        {  
            //ArgumentException,   
            //FormatException,   
            //OverflowException  
            Console.WriteLine("无效的端口号:" + e.ToString());  
            this.tbMsg.AppendText("无效的端口号:" + e.ToString() + "\n");  
            return -1;  
        }  
        return lport;  
    }  
  
  
    private IPAddress getValidIP(string ip)  
    {  
        IPAddress lip = null;  
        //测试IP是否有效  
        try  
        {  
            //是否为空  
            if (!IPAddress.TryParse(ip, out lip))  
            {  
                throw new ArgumentException(  
                    "IP无效,不能启动DUP");  
            }  
        }  
        catch (Exception e)  
        {  
            //ArgumentException,   
            //FormatException,   
            //OverflowException  
            Console.WriteLine("无效的IP:" + e.ToString());  
            this.tbMsg.AppendText("无效的IP:" + e.ToString() + "\n");  
            return null;  
        }  
        return lip;  
    }  

4. Socket configuration
//得到本机IP,设置UDP端口号     
ip = getValidIP(tbLocalIP.Text);  
port = getValidPort(tbLocalPort.Text);  
ipLocalPoint = new IPEndPoint(ip, port);  
  
//定义网络类型,数据连接类型和网络协议UDP  
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  
  
//绑定网络地址  
mySocket.Bind(ipLocalPoint);  
  
//得到客户机IP  
ip = getValidIP(tbRemoteIP.Text);  
port = getValidPort(tbRemotePort.Text);  
IPEndPoint ipep = new IPEndPoint(ip, port);  
RemotePoint = (EndPoint)(ipep);  
  
//启动一个新的线程,执行方法this.ReceiveHandle,  
//以便在一个独立的进程中执行数据接收的操作  
  
RunningFlag = true;  
Thread thread = new Thread(new ThreadStart(this.ReceiveHandle));  
thread.Start();  

5. Receiving thread
//定义一个委托  
public delegate void MyInvoke(string strRecv);  
private void ReceiveHandle()  
{  
    //接收数据处理线程  
    string msg;  
    byte[] data=new byte[1024];  
    MyInvoke myI = new MyInvoke(UpdateMsgTextBox);  
    while (RunningFlag)  
    {  
          
        if (mySocket == null || mySocket.Available < 1)  
        {  
            Thread.Sleep(200);  
            continue;  
        }  
        //跨线程调用控件  
         //接收UDP数据报,引用参数RemotePoint获得源地址  
         int rlen = mySocket.ReceiveFrom(data, ref RemotePoint);  
        msg = Encoding.Default.GetString(data, 0, rlen);  
        tbMsg.BeginInvoke(myI, new object[]{RemotePoint.ToString() + " : " + msg});  
          
    }  
}  
private void btSend_Click(object sender, EventArgs e)  
{  
    string msg;  
    msg = tbSendMsg.Text;  
    //发送UDP数据包  
    byte[] data = Encoding.Default.GetBytes(msg);  
    mySocket.SendTo(data, data.Length, SocketFlags.None, RemotePoint);  
}  
private void UpdateMsgTextBox(string msg)  
{  
    //接收数据显示  
    this.tbMsg.AppendText( msg + "\n");  
}

The above only needs to set the local and remote IP and port numbers, and it is easy to realize the two-way communication of UDP. Although UDP data packets cannot guarantee reliable transmission, factors such as busy network and congestion may prevent data packets from reaching the designated destination. But after testing, its communication is quite reliable, don't forget that QQ also uses UDP for instant communication.

Guess you like

Origin blog.csdn.net/youarenotme/article/details/72189096