C#中通过Socket实现一个简单的TCP\IP服务器和客户端的搭建 您所在的位置:网站首页 c语言socket客户端和服务端代码一样吗 C#中通过Socket实现一个简单的TCP\IP服务器和客户端的搭建

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

2024-07-05 08:10| 来源: 网络整理| 查看: 265

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有