C#中通过Socket实现一个简单的TCP\IP服务器和客户端的搭建

TCP\IP 是什么?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

Socket 是什么?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

C#中通过Socket实现一个简单的TCP\IP服务器和客户端的搭建_第1张图片

1. 实验目的:

C#中通过Socket实现一个简单的TCP\IP服务器和客户端的搭建_第2张图片
服务器端——上代码:

//   TCP/IP
using System.Net;
using System.Net.Sockets;

namespace TCPIP异步通讯
{
     
    public class TCP_Server
    {
     
        public TCP_Server(string Ip, int Port)
        {
     
            this.ipAndPoint = new IPEndPoint(IPAddress.Parse(Ip), Port);
            this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
        public DataExchange tmp = new DataExchange();
        public delegate void DelDataArrived(DataExchange tmp);
        public event DelDataArrived OnDataArrivedEvent;  //收到数据事件
        public event DelDataArrived OnDiscoveredDeviceEvent;  //发现设备事件

        /// 
        /// IP地址和Port口
        /// 
        private IPEndPoint _IpAndPoint;
        public IPEndPoint ipAndPoint
        {
     
            get {
      return _IpAndPoint; }
            set {
      _IpAndPoint = value; }
        }

        /// 
        /// 负责监听的Socket对象
        /// 
        private Socket _MySocket;
        public Socket mySocket
        {
     
            get {
      return _MySocket; }
            set {
      _MySocket = value; }
        }

        /// 
        /// 负责收发数据的Socket对象
        /// 
        private Socket _ConnectSocket;
        public Socket ConnectSocket
        {
     
            get {
      return _ConnectSocket; }
            set {
      _ConnectSocket = value; }
        }
        /// 
        /// 服务器开始监听
        /// 
        public void StartListen()
        {
     
            mySocket.Bind(ipAndPoint);
            mySocket.Listen(10);
            mySocket.BeginAccept(new AsyncCallback((iResult) =>
            {
     
                this.ConnectSocket = mySocket.EndAccept(iResult);
                if (this.ConnectSocket.Connected)
                {
     
                    if (OnDiscoveredDeviceEvent != null)
                    {
     
                        tmp.ip = this.ConnectSocket.RemoteEndPoint;
                        OnDiscoveredDeviceEvent(tmp);
                    }
                    Task task = ReceiveDataFromClient(this.ConnectSocket);
                }
            }), null);
        }
        public Task ReceiveDataFromClient(Socket rcvSocket)
        {
     
            return Task.Run(() =>
            {
     
                using (rcvSocket)
                {
     
                    while (true)
                    {
     
                        byte[] byt = new byte[1024]; 
                        int len = rcvSocket.Receive(byt, 0, byt.Length, SocketFlags.None);
                        tmp.data = Encoding.Default.GetString(byt, 0, len);
                        if (OnDataArrivedEvent != null)
                        {
     
                            OnDataArrivedEvent(tmp);
                        }
                    }
                }
            });
        }
         /// 
        /// 发送数据给客户端
        /// 
        /// 
        public void Send(string Msg)
        {
     
            try
            {
     
                byte[] bytStr = Encoding.Default.GetBytes(Msg);
                this.ConnectSocket.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
                {
     
                    Socket Skt = (Socket)iar.AsyncState;
                    int length = this.ConnectSocket.EndSend(iar);
                }), this.ConnectSocket);
            }
            catch (Exception ex)
            {
     
                throw new Exception(ex.Message.ToString());
            }
        }
    }
     /// 
    /// 数据交换类,用于传递数据
    /// 
    public class DataExchange : EventArgs
    {
     
        private EndPoint _IP;
        public EndPoint ip
        {
     
            get {
      return _IP; }
            set {
      _IP = value; }
        }

        private Socket _TmpSkt;
        public Socket tmpSkt
        {
     
            get {
      return _TmpSkt; }
            set {
      _TmpSkt = value; }
        }

        private string _Data;
        public string data
        {
     
            get {
      return _Data; }
            set {
      _Data = value; }
        }
    }

客户端——上代码:

//   TCP/IP
using System.Net;
using System.Net.Sockets;

namespace TCPIP异步通讯
{
     
    public class TCP_Client
    {
     
        public TCP_Client(string Ip, int Port)
        {
     
            this.ipAndPoint = new IPEndPoint(IPAddress.Parse(Ip), Port);
            this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        public DataExchange_Client tmp = new DataExchange_Client();
        public delegate void DelDataArrived(DataExchange_Client tmp);
        public event DelDataArrived OnDataArrivedEvent;  //收到数据事件
         /// 
        /// IP地址和Port口
        /// 
        private IPEndPoint _IpAndPoint;
        public IPEndPoint ipAndPoint
        {
     
            get {
      return _IpAndPoint; }
            set {
      _IpAndPoint = value; }
        }

        /// 
        /// 负责连接的Socket对象
        /// 
        private Socket _MySocket;
        public Socket mySocket
        {
     
            get {
      return _MySocket; }
            set {
      _MySocket = value; }
        }

        /// 
        /// 负责收发数据的Socket对象
        /// 
        private Socket _ConnectSocket;
        public Socket ConnectSocket
        {
     
            get {
      return _ConnectSocket; }
            set {
      _ConnectSocket = value; }
        }
        public void StartConnect()
        {
     
            mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            mySocket.BeginConnect(ipAndPoint, new AsyncCallback((iar) =>
            {
     
                Socket mySkt = (Socket)iar.AsyncState;
                mySocket.EndConnect(iar);
                Task taks = ReceiveDataFromServer(mySocket);
            }), null);
        }
        public Task ReceiveDataFromServer(Socket rcvSocket)
        {
     
            return Task.Run(() =>
            {
     
                using (rcvSocket)
                {
     
                    do
                    {
     
                        byte[] readBuffer = new byte[1024];
                        int readLen = rcvSocket.Receive(readBuffer, 0, readBuffer.Length, SocketFlags.None);
                        if (OnDataArrivedEvent != null)
                        {
     
                            tmp.data = Encoding.Default.GetString(readBuffer, 0, readLen);
                            OnDataArrivedEvent(tmp);
                        }
                    }
                    while (true);
                }
            });
        }

        public void Send(string Msg)
        {
     
            try
            {
     
                byte[] bytStr = Encoding.Default.GetBytes(Msg);
                mySocket.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
                {
     
                    Socket Skt = (Socket)iar.AsyncState;
                    int length = mySocket.EndSend(iar);
                }), mySocket);
            }
            catch (Exception ex)
            {
     
                throw new Exception(ex.Message.ToString());
            }
        }
    }
     /// 
    /// 数据交换类,用于传递数据
    /// 
    public class DataExchange_Client : EventArgs
    {
     
        private EndPoint _IP;
        public EndPoint ip
        {
     
            get {
      return _IP; }
            set {
      _IP = value; }
        }

        private Socket _TmpSkt;
        public Socket tmpSkt
        {
     
            get {
      return _TmpSkt; }
            set {
      _TmpSkt = value; }
        }

        private string _Data;
        public string data
        {
     
            get {
      return _Data; }
            set {
      _Data = value; }
        }
    }
}

服务器调用:

 DataExchange tmp = new DataExchange();
 TCP_Server Server = new TCP_Server(string ip, int port);

 //订阅发现设备事件
 Server.OnDiscoveredDeviceEvent += new TCP_Server.DelDataArrived((tmp) =>
 {
     
 	//编写发现客户端后要做的事。。。
 	string ip = tmp.ip;
 }

 //订阅接收数据事件     
 Server.OnDataArrivedEvent += new TCP_Server.DelDataArrived((tmp) =>
 {
     
 	//编写接收到数据之后要做的事。。。
 	string data = tmp.data;
 }
 
 //开始监听
 Server.StartListen();

客户端调用:

 DataExchange_Client tmp = new DataExchange_Client();
 TCP_Client Client = new TCP_Client(string ip, int port);
 Client.OnDataArrivedEvent += new TCP_Client.DelDataArrived((tmp) =>
 {
     
     //编写收到服务器的数据后执行的代码
     string data = tmp.data;
 });

 //开始连接
 Client.StartConnect();

以上代码有一个不足就是,服务器可以接收多个客户端发来的数据,但是无法发送数据给多个客户端,因为负责通信的Socket对象已经被写成唯一的了。
如果需要发送数据给多个客户端,则可以将服务器 Accept 到的Socket对象依次添加在一个集合中,并在Send() 方法参数列表中将Socket类型对象传入,调用 Send() 方法。如下:

 /// 
 /// 发送数据给客户端
 /// 发送数据的Socket对象
 /// 要发送的数据
 public void Send(Socket skt, string Msg)
 {
     
     try
     {
     
        byte[] bytStr = Encoding.Default.GetBytes(Msg);
        skt.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
        {
     
             Socket Skt = (Socket)iar.AsyncState;
             int length = skt.EndSend(iar);
        }), skt);
      }
      catch (Exception ex)
      {
     
         throw new Exception(ex.Message.ToString());
      }
 }

以上,如有错误,欢迎及时批评指正,谢谢。。。

你可能感兴趣的:(C#)