一、Socket编程
Socket即为套接字,它其实是一个句柄,存在于内存中的一个标识符,作为网络通信的一个符号。
Socket类位于System.Net.Sockets命名空间,封装了与套接字编程相关的API,其内部调用了与WInsock相关的WIn32 API。
网络通信至少有两个通信终端,一般来说,监听并接受连续的一端称为服务器,而发送请求的一方称为客户端。
二、Socket类的使用步骤
1、服务器
(1)实例化Socket对象。
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
(2)调用Bind方法绑定本地终结点。需要指定一个本地IP地址和一个本地端口,Socket将在该终结点上监听传入的客户端连接。(注意绑定饿端口号必须为系统暂未分配的,否则指定端口号无效,无法建立连接)
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8622); server.Bind(endpoint);
(3)调用Listen方法开始监听客户端连接。
server.Listen(15);
(4)调用Accept相关方法接收连接,并返回一个用于与客户端进行通信的Socket实例。
server.BeginAccept(new AsyncCallback(Accpcallback), server); private static void Accpcallback(IAsyncResult ar) { Socket server = (Socket)ar.AsyncState; Socket client = server.EndAccept(ar); string remoteendpoint = client.RemoteEndPoint.ToString(); Console.WriteLine("已接受客户端【0】的连接。" + remoteendpoint); byte[] data = Encoding.UTF8.GetBytes("您好,服务器已经接受连接了。"); int len = data.Length; client.Send(BitConverter.GetBytes(len)); client.Send(data); client.Close(); Console.ReadLine(); server.BeginAccept(new AsyncCallback(Accpcallback), server); }
(5)通过Send方法和Recieve方法进行收发数据。
(6)通信结束后调用Close关闭Socket对象。
2、客户端
(1)实例化Socket。
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
(2)调用Connect方法进行连接,需要指定服务器的地址和端口,服务器的端口必须与服务器绑定的监听端口一致,否则无法连接。
client.Connect("127.0.0.1", 8622);
(3)调用Send和Recieve方法收发数据。对于未进行连接的Socket对象,可以使用RecieveFrom和SendTo来进行通信。
(4)通信结束后关闭Socket对象。
3、连接示意图
三、服务器,客户端源代码
客户端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace tcpclient { class Program { static void Main(string[] args) { Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { client.Connect("127.0.0.1", 8622); string remoteendpoint = client.RemoteEndPoint.ToString(); Console.WriteLine("成功连接服务器【0】。" + remoteendpoint); byte[] buffer = new byte[4]; client.Receive(buffer); int len = BitConverter.ToInt32(buffer, 0); buffer = new byte[len]; client.Receive(buffer); string msg = Encoding.UTF8.GetString(buffer); Console.WriteLine("从服务器接收到消息: " + msg); Console.ReadLine(); } catch (SocketException ex) { Console.WriteLine(ex.Message); } } } }
服务器
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace tcpserver { class Program { static void Main(string[] args) { Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8622); server.Bind(endpoint); server.Listen(15); server.BeginAccept(new AsyncCallback(Accpcallback), server); Console.ReadLine(); } private static void Accpcallback(IAsyncResult ar) { Socket server = (Socket)ar.AsyncState; Socket client = server.EndAccept(ar); string remoteendpoint = client.RemoteEndPoint.ToString(); Console.WriteLine("已接受客户端【0】的连接。" + remoteendpoint); byte[] data = Encoding.UTF8.GetBytes("您好,服务器已经接受连接了。"); int len = data.Length; client.Send(BitConverter.GetBytes(len)); client.Send(data); client.Close(); Console.ReadLine(); server.BeginAccept(new AsyncCallback(Accpcallback), server); } } }
源码下载地址:
http://download.csdn.net/detail/kevin_iot/9749747
注意:以上为两个项目,必须两个项目全部运行才能完成客户端与服务端的连接
如何同时建立两个项目?在已有的项目基础上,右键解决方案,新建新的项目。
如何同时运行多个项目?打开解决方案属性窗口,把启动方式改为“多启动项目”,并且将两个项目都标记为“启动”。
如何验证程序的执行步骤?设置断电,一步步执行,看执行步骤是否为示意图所示。
运行结果
参考文章:
C#网络编程基本字段——IPAddress、IPEndPoint
参考书籍: