이 글에서는 UDP 프로토콜 통신을 구현하기 위한 C#의 소켓 샘플 코드를 주로 소개하고 있는데, 편집자가 보기엔 꽤 좋다고 생각해서 지금부터 공유하고 참고용으로 올려보겠습니다.
오늘은 UDP를 이용한 분산통신 시뮬레이션 시스템의 기반을 마련하기 위해 C#의 소켓을 이용하여 UDP 통신을 검증하는 시간을 가졌습니다. 우리 모두 알고 있듯이 UDP는 전송 계층인 인터넷 참조 모델 의 네 번째 계층인 사용자 데이터그램 프로토콜입니다. TCP 프로토콜과 동일한 계층에서 둘 다 정보 전송 서비스를 제공하지만 TCP와의 가장 큰 차이점은 연결이 없고 신뢰할 수 없는 정보 전송이라는 점입니다.
연결되지 않은 신뢰성이란 무엇입니까? 직설적으로 말하면, 데이터를 보낼 때 UDP 패킷을 네트워크에 던지기만 하면 됩니다. 데이터를 받을 때 로컬로 보낸 UDP 패킷이 있으면 수신 여부는 중요하지 않습니다. 모두 수집한 후 수집한 후 누가 보냈는지 확인하세요. TCP에 비해 연결을 설정하고 연결을 유지하고 연결을 해제하기 위한 핸드셰이킹 등 일련의 과정이 필요하지 않아 리소스 소모가 적고 처리 속도가 빠른 장점이 있습니다.
이제 쓸데없는 말을 많이 했으니 UDP 통신을 위해 C#에서 소켓을 사용하는 방법에 대해 이야기해 보겠습니다. TCP 및 UDP 애플리케이션은 TCPClient, TCPListener 및 UDPClient 클래스를 통해 프로그래밍할 수 있으며 이러한 프로토콜 클래스도 System.Net.Sockets.Socket 클래스를 기반으로 하므로 데이터 전송 세부 사항을 걱정할 필요가 없습니다. . 그러나 소켓 프로그래밍을 더 잘 이해하기 위해 UDP 통신 프로그래밍에는 여전히 소켓 클래스가 사용됩니다.
UDP 애플리케이션에서는 엄밀한 의미에서 더 이상 실제 서버와 클라이언트 사이에 구분이 없습니다. 따라서 통신하는 데는 하나의 프로그램만 필요합니다.
코드의 주요 부분과 설명은 다음과 같습니다.
주요 전역 변수
private IPEndPoint ipLocalPoint; private EndPoint RemotePoint; private Socket mySocket; private bool RunningFlag = false;
로컬 IP를 얻는 방법
private string getIPAddress() { // 获得本机局域网IP地址 IPAddress[] AddressList = Dns.GetHostByName(Dns.GetHostName()).AddressList; if (AddressList.Length < 1) { return ""; } return AddressList[0].ToString(); }
IP 및 포트 유효한 숫자 확인
private int getValidPort(string port) { int lport; //测试端口号是否有效 try { //是否为空 if (port == "") { throw new ArgumentException( "端口号无效,不能启动DUP"); } 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; }
소켓 구성
//得到本机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();
수신 스레드
//定义一个委托 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"); }
위에서는 로컬 및 원격 IP와 포트 번호만 설정하면 되며 두 가지를 쉽게 실현할 수 있습니다. UDP의 양방향 통신. UDP 데이터 패킷은 안정적인 전송을 보장할 수 없지만 네트워크 사용량, 정체 및 기타 요인으로 인해 데이터 패킷이 지정된 대상에 도달하지 못할 수 있습니다. 그러나 테스트 후에는 QQ가 UDP를 사용하여 즉각적인 통신을 수행한다는 사실을 잊지 마십시오.
위 내용은 C#의 소켓을 이용하여 UDP 프로토콜 통신을 구현하기 위한 샘플 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!