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

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

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

在这里插入图片描述

1. 实验目的:

在这里插入图片描述
服务器端——上代码:

//   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;  //发现设备事件

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

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

        /// <summary>
        /// 负责收发数据的Socket对象
        /// </summary>
        private Socket _ConnectSocket;
        public Socket ConnectSocket
        {
            get { return _ConnectSocket; }
            set { _ConnectSocket = value; }
        }
        /// <summary>
        /// 服务器开始监听
        /// </summary>
        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);
                        }
                    }
                }
            });
        }
         /// <summary>
        /// 发送数据给客户端
        /// </summary>
        /// <param name="Msg"></param>
        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());
            }
        }
    }
     /// <summary>
    /// 数据交换类,用于传递数据
    /// </summary>
    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;  //收到数据事件
         /// <summary>
        /// IP地址和Port口
        /// </summary>
        private IPEndPoint _IpAndPoint;
        public IPEndPoint ipAndPoint
        {
            get { return _IpAndPoint; }
            set { _IpAndPoint = value; }
        }

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

        /// <summary>
        /// 负责收发数据的Socket对象
        /// </summary>
        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());
            }
        }
    }
     /// <summary>
    /// 数据交换类,用于传递数据
    /// </summary>
    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() 方法。如下:

 /// <summary>
 /// 发送数据给客户端
 /// <param name="skt">发送数据的Socket对象</param>
 /// <param name="Msg">要发送的数据</param>
 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());
      }
 }

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

  • 11
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是一个简单C# Socket客户端服务器的代码示例: 服务器端代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; class Server { static void Main(string[] args) { IPAddress ipAddress = IPAddress.Any; int port = 12345; TcpListener listener = new TcpListener(ipAddress, port); listener.Start(); Console.WriteLine("Server started on " + ipAddress.ToString() + ":" + port); while (true) { TcpClient client = listener.AcceptTcpClient(); Console.WriteLine("Client connected: " + client.Client.RemoteEndPoint.ToString()); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string message = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("Received message from client: " + message); byte[] data = Encoding.ASCII.GetBytes("Hello from server!"); stream.Write(data, 0, data.Length); client.Close(); } } } ``` 客户端代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; class Client { static void Main(string[] args) { IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); int port = 12345; TcpClient client = new TcpClient(); client.Connect(ipAddress, port); Console.WriteLine("Connected to server on " + ipAddress.ToString() + ":" + port); NetworkStream stream = client.GetStream(); string message = "Hello from client!"; byte[] data = Encoding.ASCII.GetBytes(message); stream.Write(data, 0, data.Length); Console.WriteLine("Sent message to server: " + message); byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string response = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("Received message from server: " + response); client.Close(); } } ``` 在这个例子服务器监听指定的IP地址和端口,当客户端连接时会处理客户端发送的消息,并回复一个简单的消息。客户端连接到服务器,发送一个简单的消息并等待服务器的响应。请注意,这个示例仅用于演示目的,实际实现时需要考虑更多的异常处理和安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值