목차
이 기사에서는
소켓 동기화 UDP 서버
백엔드 개발 C#.Net 튜토리얼 C# 네트워크 프로그래밍 시리즈 기사 (6) 소켓은 동기 UDP 서버를 구현합니다.

C# 네트워크 프로그래밍 시리즈 기사 (6) 소켓은 동기 UDP 서버를 구현합니다.

Feb 27, 2017 am 11:22 AM

이 기사에서는

.Net에서 System.Net.Sockets 네임스페이스는 네트워크 액세스를 엄격하게 제어해야 하는 개발자를 위해 Windows 소켓(Winsock) 인터페이스의 관리형 구현을 제공합니다. System.Net 네임스페이스의 다른 모든 네트워크 액세스 클래스는 이 소켓 구현을 기반으로 구축되었습니다. TCPClient, TCPListener 및 UDPClient 클래스는 인터넷에 대한 TCP 및 UDP 연결 생성에 대한 자세한 정보를 캡슐화합니다. NetworkStream 클래스는 네트워크의 기본 데이터 흐름을 제공합니다. 액세스, 소켓은 텔넷, HTTP, 이메일, 에코 등과 같은 많은 일반적인 인터넷 서비스에서 볼 수 있습니다. 이러한 서비스는 통신 프로토콜에 대해 서로 다른 정의를 가지고 있지만 기본 전송은 소켓을 사용합니다. 실제로 소켓은 스트림과 같은 데이터 채널로 간주할 수 있습니다. 이 채널은 애플리케이션(클라이언트)과 원격 서버 사이에 설정되며 이 채널을 통해 데이터 읽기(수신)와 쓰기(전송)가 모두 수행됩니다. .
애플리케이션 측이나 서버 측에서 Socket 객체를 생성한 후 Send/SentTo 메소드를 이용하여 연결된 Socket으로 데이터를 보내거나, Receiver/ReceiveFrom 메소드를 이용하여 연결된 Socket으로부터 데이터를 받을 수 있음을 알 수 있다. 소켓;
소켓 프로그래밍의 경우 .NET Framework의 Socket 클래스는 Winsock32 API에서 제공하는 소켓 서비스의 관리 코드 버전입니다. 네트워크 프로그래밍을 구현하기 위해 제공되는 여러 메서드가 있으며 대부분의 경우 Socket 클래스 메서드는 단순히 데이터를 기본 Win32 복사본으로 마샬링하고 필요한 보안 검사를 처리합니다. Winsock API 함수에 익숙하다면 Socket 클래스를 사용하여 네트워크 프로그램을 작성하는 것이 매우 쉬울 것입니다. 물론, 한 번도 사용해 본 적이 없다면 아래 설명을 따르면 크게 어렵지 않을 것입니다. Windows 네트워크 응용 프로그램을 개발하기 위해 Socket 클래스를 사용하는 것은 실제로 규칙이 있으며 대부분의 경우 거의 동일한 단계를 따릅니다.


이 섹션에서는 소켓을 사용하여 동기식 UDP 서버를 구현하는 방법을 소개합니다.

소켓 동기화 UDP 서버


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace NetFrame.Net.UDP.Sock.Synchronous
{
    /// <summary>
    /// Socket 实现同步UDP服务器
    /// </summary>
    public class SocketUDPServer
    {
        #region Fields
        /// <summary>
        /// 服务器程序允许的最大客户端连接数
        /// </summary>
        private int _maxClient;

        /// <summary>
        /// 当前的连接的客户端数
        /// </summary>
        private int _clientCount;

        /// <summary>
        /// 服务器使用的同步socket
        /// </summary>
        private Socket _serverSock;

        /// <summary>
        /// 客户端会话列表
        /// </summary>
        private List<SocketUDPState> _clients;

        private bool disposed = false;

        /// <summary>
        /// 数据接受缓冲区
        /// </summary>
        private byte[] _recvBuffer;

        #endregion

        #region Properties

        /// <summary>
        /// 服务器是否正在运行
        /// </summary>
        public bool IsRunning { get; private set; }
        /// <summary>
        /// 监听的IP地址
        /// </summary>
        public IPAddress Address { get; private set; }
        /// <summary>
        /// 监听的端口
        /// </summary>
        public int Port { get; private set; }
        /// <summary>
        /// 通信使用的编码
        /// </summary>
        public Encoding Encoding { get; set; }

        #endregion

        #region 构造函数

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="listenPort">监听的端口</param>
        public SocketUDPServer(int listenPort)
            : this(IPAddress.Any, listenPort,1024)
        {
        }

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="localEP">监听的终结点</param>
        public SocketUDPServer(IPEndPoint localEP)
            : this(localEP.Address, localEP.Port,1024)
        {
        }

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="localIPAddress">监听的IP地址</param>
        /// <param name="listenPort">监听的端口</param>
        /// <param name="maxClient">最大客户端数量</param>
        public SocketUDPServer(IPAddress localIPAddress, int listenPort, int maxClient)
        {
            this.Address = localIPAddress;
            this.Port = listenPort;
            this.Encoding = Encoding.Default;

            _maxClient = maxClient;
            _clients = new List<SocketUDPState>();
            _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            _recvBuffer=new byte[_serverSock.ReceiveBufferSize];
        }

        #endregion

        #region Method
        /// <summary>
        /// 启动服务器
        /// </summary>
        /// <returns>异步TCP服务器</returns>
        public void Start()
        {
            if (!IsRunning)
            {
                IsRunning = true;
                _serverSock.Bind(new IPEndPoint(this.Address, this.Port));
                //启动一个线程监听数据
                new Thread(ReceiveData).Start();
            }
        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        public void Stop()
        {
            if (IsRunning)
            {
                IsRunning = false;
                _serverSock.Close();
                //TODO 关闭对所有客户端的连接
                CloseAllClient();
            }
        }

        /// <summary>
        /// 同步数据接收方法
        /// </summary>
        private void ReceiveData()
        {
            int len = -1;
            EndPoint remote = null;
            while (true)
            {
                try
                {
                    len = _serverSock.ReceiveFrom(_recvBuffer, ref remote);

                    //if (!_clients.Contains(remote))
                    //{
                    //    _clients.Add(remote);
                    //}
                }
                catch (Exception)
                {
                    //TODO 异常处理操作
                    RaiseOtherException(null);
                }
            }
        }
        /// <summary>
        /// 同步发送数据
        /// </summary>
        public void Send(string msg, EndPoint clientip)
        {
            byte[] data = Encoding.Default.GetBytes(msg);
            try
            {
                _serverSock.SendTo(data, clientip);
                //数据发送完成事件
                RaiseCompletedSend(null);
            }
            catch (Exception)
            {
                //TODO 异常处理
                RaiseOtherException(null);
            }
        }

        #endregion

        #region 事件
        /// <summary>
        /// 接收到数据事件
        /// </summary>
        public event EventHandler<SocketUDPEventArgs> DataReceived;

        private void RaiseDataReceived(SocketUDPState state)
        {
            if (DataReceived != null)
            {
                DataReceived(this, new SocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 数据发送完毕事件
        /// </summary>
        public event EventHandler<SocketUDPEventArgs> CompletedSend;

        /// <summary>
        /// 触发数据发送完毕的事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseCompletedSend(SocketUDPState state)
        {
            if (CompletedSend != null)
            {
                CompletedSend(this, new SocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 网络错误事件
        /// </summary>
        public event EventHandler<SocketUDPEventArgs> NetError;
        /// <summary>
        /// 触发网络错误事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseNetError(SocketUDPState state)
        {
            if (NetError != null)
            {
                NetError(this, new SocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 异常事件
        /// </summary>
        public event EventHandler<SocketUDPEventArgs> OtherException;
        /// <summary>
        /// 触发异常事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseOtherException(SocketUDPState state, string descrip)
        {
            if (OtherException != null)
            {
                OtherException(this, new SocketUDPEventArgs(descrip, state));
            }
        }
        private void RaiseOtherException(SocketUDPState state)
        {
            RaiseOtherException(state, "");
        }
        #endregion

        #region Close
        /// <summary>
        /// 关闭一个与客户端之间的会话
        /// </summary>
        /// <param name="state">需要关闭的客户端会话对象</param>
        public void Close(SocketUDPState state)
        {
            if (state != null)
            {
                _clients.Remove(state);
                _clientCount--;
                //TODO 触发关闭事件
            }
        }
        /// <summary>
        /// 关闭所有的客户端会话,与所有的客户端连接会断开
        /// </summary>
        public void CloseAllClient()
        {
            foreach (SocketUDPState client in _clients)
            {
                Close(client);
            }
            _clientCount = 0;
            _clients.Clear();
        }
        #endregion

        #region 释放
        /// <summary>
        /// Performs application-defined tasks associated with freeing, 
        /// releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release 
        /// both managed and unmanaged resources; <c>false</c> 
        /// to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    try
                    {
                        Stop();
                        if (_serverSock != null)
                        {
                            _serverSock = null;
                        }
                    }
                    catch (SocketException)
                    {
                        //TODO
                        RaiseOtherException(null);
                    }
                }
                disposed = true;
            }
        }
        #endregion
    }
}
로그인 후 복사

클라이언트 상태 캡슐화 클래스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace NetFrame.Net.UDP.Sock.Synchronous
{
    public class SocketUDPState
    {
        // Client   socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();

        public EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
    }
}
로그인 후 복사


서버 이벤트 매개변수 클래스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetFrame.Net.UDP.Sock.Synchronous
{
    /// <summary>
    /// Socket实现同步UDP服务器
    /// </summary>
    public class SocketUDPEventArgs:EventArgs
    {
        /// <summary>
        /// 提示信息
        /// </summary>
        public string _msg;

        /// <summary>
        /// 客户端状态封装类
        /// </summary>
        public SocketUDPState _state;

        /// <summary>
        /// 是否已经处理过了
        /// </summary>
        public bool IsHandled { get; set; }

        public SocketUDPEventArgs(string msg)
        {
            this._msg = msg;
            IsHandled = false;
        }
        public SocketUDPEventArgs(SocketUDPState state)
        {
            this._state = state;
            IsHandled = false;
        }
        public SocketUDPEventArgs(string msg, SocketUDPState state)
        {
            this._msg = msg;
            this._state = state;
            IsHandled = false;
        }
    }
}
로그인 후 복사

위 내용은 C# 네트워크 프로그래밍 시리즈 기사(6)의 UDP 서버 동기화를 위한 소켓 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

C#을 사용한 Active Directory C#을 사용한 Active Directory Sep 03, 2024 pm 03:33 PM

C#을 사용한 Active Directory 가이드. 여기에서는 소개와 구문 및 예제와 함께 C#에서 Active Directory가 작동하는 방식에 대해 설명합니다.

C#의 난수 생성기 C#의 난수 생성기 Sep 03, 2024 pm 03:34 PM

C#의 난수 생성기 가이드입니다. 여기서는 난수 생성기의 작동 방식, 의사 난수 및 보안 숫자의 개념에 대해 설명합니다.

C#의 액세스 한정자 C#의 액세스 한정자 Sep 03, 2024 pm 03:24 PM

C#의 액세스 수정자에 대한 안내입니다. 예제 및 출력과 함께 C#의 액세스 한정자의 소개 유형에 대해 논의했습니다.

C# 데이터 그리드 보기 C# 데이터 그리드 보기 Sep 03, 2024 pm 03:32 PM

C# 데이터 그리드 뷰 가이드. 여기서는 SQL 데이터베이스 또는 Excel 파일에서 데이터 그리드 보기를 로드하고 내보내는 방법에 대한 예를 설명합니다.

C# 직렬화 C# 직렬화 Sep 03, 2024 pm 03:30 PM

C# 직렬화 가이드. 여기에서는 C# 직렬화 개체의 소개, 단계, 작업 및 예제를 각각 논의합니다.

C#의 패턴 C#의 패턴 Sep 03, 2024 pm 03:33 PM

C#의 패턴 가이드. 여기에서는 예제 및 코드 구현과 함께 C#의 패턴 소개 및 상위 3가지 유형에 대해 설명합니다.

C#의 소수 C#의 소수 Sep 03, 2024 pm 03:35 PM

C#의 소수 가이드. 여기서는 코드 구현과 함께 C#의 소수에 대한 소개와 예를 논의합니다.

C#의 팩토리얼 C#의 팩토리얼 Sep 03, 2024 pm 03:34 PM

C#의 팩토리얼 가이드입니다. 여기서는 다양한 예제 및 코드 구현과 함께 C#의 계승에 대한 소개를 논의합니다.

See all articles