.NET下Socket编程的一个实例

本文提供了一个异步Socket编程的示例,包括服务器端和客户端的代码实现。通过使用.NET框架,演示了如何建立连接、发送和接收数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前些天在网上看到了一个Socket编程的例子,不过只有服务器端的代码。看了以后心理就开始痒痒了,所以就把它修改了一下,并且添加客户端的代码,现在贴出来,希望大家能批评指正。本例子采用的是异步通讯的方式。

服务器端代码:

using System;

using System.Threading;

using System.Net;

using System.Net.Sockets;

using System.Windows.Forms;

using System.Text;

using System.Diagnostics;



namespace SocketTestServe

{

	/// <summary>

	/// XmlSocket 的摘要说明。

	/// </summary>

	public class SocketServe

	{

		public SocketServe()

		{

		}

		//结束标志

		public static bool overFlag = true;

		//异步socket诊听

		// Incoming data from client.从客户端传来的数据

		public static string data = null;



		// Thread signal.线程 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。

		public static ManualResetEvent allDone = new ManualResetEvent(false);



		public static string ms_ReceData;

		public static string ms_SendData = "数据以收到!/n";



		private static Socket listener;

		public static void StartListening()

		{

			// Data buffer for incoming data. 传入数据缓冲

			byte[] bytes = new byte[1024];

			// Establish the local endpoint for the socket. 建立本地端口

			// The DNS name of the computer

			// running the listener is "host.contoso.com".

			IPAddress ipAddress;//本机IP



			String ipString = String.Empty;



			IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());

			ipAddress = ipHostInfo.AddressList[0];



			String portString = "9000";

			int port = int.Parse(portString);//本机端口

			

			IPEndPoint localEndPoint = new IPEndPoint(ipAddress,port);



			// Create a TCP/IP socket.

			listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);



			// Bind the socket to the local endpoint and listen for incoming connections.绑定端口和数据

			listener.Bind(localEndPoint);

			listener.Listen(100);



			//启动一个线程来进行监听,否则 

			Thread listenThread = new Thread(new ThreadStart(SocketListen));

			listenThread.Start();

		}



		private static void SocketListen()

		{

			try

			{

				while(overFlag)

				{

					// Set the event to nonsignaled state.设置无信号状态的事件

					allDone.Reset();

					// Start an asynchronous socket to listen for connections.重新 启动异步连接

					listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);

					// Wait until a connection is made before continuing.等待连接创建后继续

					allDone.WaitOne();

				}

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		public static void AcceptCallback(IAsyncResult ar)

		{

			try

			{

				//Signal the main thread to continue.接受回调方法 该方法的此节向主应用程序线程发出信号,

				//让它继续处理并建立与客户端的连接

				System.Diagnostics.Debug.WriteLine("AcceptCallback1");

				allDone.Set();

				System.Diagnostics.Debug.WriteLine("AcceptCallback2");

				Socket listener = (Socket)ar.AsyncState;

				Socket handler = listener.EndAccept(ar);

				// Create the state object.

				StateObject state = new StateObject();

				state.workSocket = handler;

				handler.BeginReceive(state.buffer,0,state.BufferSize,0,

					new AsyncCallback(ReadCallBack),state);

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		/// <summary>

		/// 与接受回调方法一样,读取回调方法也是一个 AsyncCallback 委托。

		/// 该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。

		/// 从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。

		/// </summary>

		/// <param name="ar">IAsyncResult 委托</param>

		public static void ReadCallBack(IAsyncResult ar)

		{

			try

			{

				StateObject state = (StateObject)ar.AsyncState;

				Socket handler = state.workSocket;//处理的句柄

				// Read data from the client socket. 读出

				int bytesRead = handler.EndReceive(ar);

				if(bytesRead > 0)

				{

					string result = Encoding.UTF8.GetString(state.buffer);

					//添加自己的处理代码

					ms_SendData = ms_SendData + result;

					//向客户端发送响应消息

					Send(ms_SendData,handler);

				}

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		private static void  Send(String data,Socket handler)

		{

			try

			{

				// Convert the string data to byte data using UTF8 encoding.

				byte[] byteData = Encoding.UTF8.GetBytes(data);

				// Begin sending the data to the remote device.

				handler.BeginSend(byteData,0,byteData.Length,0,

					new AsyncCallback(SendCallback),handler);

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		/// <summary>

		/// 发送

		/// </summary>

		/// <param name="ar"></param>

		private static void SendCallback(IAsyncResult ar)

		{

			try

			{

				// Retrieve the socket from the state object.

				Socket handler = (Socket)ar.AsyncState;

				// Complete sending the data to the remote device.向远端发送数据

				int byteSend = handler.EndSend(ar);

				//结束链接

				handler.Shutdown(SocketShutdown.Both);

				handler.Close();

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		public static void StopListening()

		{

			try

			{

				allDone.Set();

				allDone.Close();

			}

			catch(Exception exc)

			{

				Debug.WriteLine(exc.Message);

			}

			overFlag = false;

		}

	}

}

客户端代码:
using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.Text;

using System.Windows.Forms;



namespace SocketTestClient

{

	/// <summary>

	/// SocketClient 的摘要说明。

	/// </summary>

	public class SocketClient

	{

		public SocketClient()

		{

		}

		// Thread signal.线程 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。

		public static ManualResetEvent allDone = new ManualResetEvent(false);



		public static string ms_SendData;

		public static string ms_ReceData;



		private static Client ms_Form = new Client();

		public static void StartSend()

		{

			//服务器IP和端口

			String ipString = "192.168.0.10";//服务器IP

			IPAddress clientIP = IPAddress.Parse(ipString);



			//本机IP和端口

			IPAddress serveIP;

			IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());

			serveIP = ipHostInfo.AddressList[0];



			String portString = "9000";

			int port = int.Parse(portString);



			IPEndPoint serveEndPoint = new IPEndPoint(clientIP,port);

			IPEndPoint localEndPoint = new IPEndPoint(serveIP,port);



			// Create a TCP/IP socket.

			Socket connecter = new Socket(AddressFamily.InterNetwork,

				SocketType.Stream, ProtocolType.Tcp);



			//获得发送数据

			byte[] byteData = Encoding.UTF8.GetBytes(ms_SendData);

			try

			{

				//绑定本地端口

				connecter.Bind(localEndPoint);

				//链接到服务器

				connecter.Connect(serveEndPoint);

				//发送数据

				connecter.BeginSend(byteData,0,byteData.Length,0,

					new AsyncCallback(SendCallback),connecter);



				allDone.WaitOne();

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		private static void SendCallback(IAsyncResult ar)

		{

			try

			{

				// Retrieve the socket from the state object.

				Socket handler = (Socket)ar.AsyncState;

				// Complete sending the data to the remote device.向远端发送数据

				int byteSend = handler.EndSend(ar);

				allDone.Set();



				//接受服务器返回数据

				if(byteSend > 0)

				{

					StateObject state = new StateObject();

					state.workSocket = handler;



					allDone.Reset();

					handler.BeginReceive(state.buffer,0,state.BufferSize,0,

						new AsyncCallback(ReadCallback),state);

					allDone.WaitOne();

				}



				handler.Shutdown(SocketShutdown.Both);

				handler.Close();

				allDone.Close();

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}



		private static void ReadCallback(IAsyncResult ar)

		{

			try

			{

				StateObject state = (StateObject)ar.AsyncState;

				Socket handler = state.workSocket;//处理的句柄

				// Read data from the client socket. 读出

				int bytesRead = handler.EndReceive(ar);

				allDone.Set();

				//服务器返回的响应消息

				ms_ReceData = Encoding.UTF8.GetString(state.buffer);

			}

			catch(Exception exc)

			{

				MessageBox.Show(exc.Message);

			}

		}

	}

}
public class StateObject

	{

		public Socket workSocket = null;              // Client socket.

		private const int bufferSize = 4096;            // Size of receive buffer.

		public byte[] buffer = new byte[bufferSize];  // Receive buffer.

		public byte[] result_buf=null;     //接收最终的结果缓冲区  

		private int _msglength=0;      //接收到多少个字节数据 



		public int BufferSize

		{

			get

			{

				return bufferSize;

			}

		}



		public int MsgLength

		{

			get

			{

				return this._msglength;

			}

			set

			{

				this._msglength = value;

			}

		}

	}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值