首先,创建一个异步Socket服务器需要进行以下步骤:
- 创建Socket监听端口
- 等待连接
- 接收连接并分配线程进行处理
- 给客户端发送信息
- 关闭连接
下面我们来一步步讲解具体实现。
创建Socket监听端口
创建Socket监听端口相关的代码如下所示:
using System.Net;
using System.Net.Sockets;
public void StartServer()
{
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 8080)); // 监听 8080 端口
listener.Listen(5); // 设置监听队列长度为 5
Console.WriteLine("Server is listening...");
while(true)
{
Socket clientSocket = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
Console.WriteLine("Client connected.");
// 连接成功后,分配任务并等待下一个连接
Task.Run(() => ProcessClient(clientSocket));
}
}
在 StartServer() 方法中,我们创建了一个Socket实例,然后调用 Bind() 方法来将其绑定到本地任意IP地址和8080端口,最后调用 Listen() 方法来开始监听。
等待连接
创建Socket监听后,我们需要等待连接。这个过程需要一直不断地运行,直到进程关闭。具体实现代码如下:
public async Task AcceptLoop(Socket listener)
{
while (true)
{
var client = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
Console.WriteLine("Client connected.");
Task.Factory.StartNew(() => ProcessClient(client));
}
}
在 AcceptLoop() 方法中,我们使用了一个while循环,不停地等待新的连接。这个方法使用了异步等待,意味着它会释放线程资源并等待下一个客户端请求。
接收连接并分配线程进行处理
连接被接受后,我们需要为该连接分配一个新的线程来对该连接进行处理。下面的代码实现了这一功能:
public void ProcessClient(Socket clientSocket)
{
// 处理客户端请求
try
{
// 接收客户端数据
byte[] buffer = new byte[1024];
int length = clientSocket.Receive(buffer);
Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, 0, length));
// 给客户端发送响应数据
string response = "Hello from server";
clientSocket.Send(Encoding.ASCII.GetBytes(response));
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
finally
{
// 关闭连接
clientSocket.Close();
}
}
在 ProcessClient() 方法中,我们首先接收客户端发送的数据,然后对其进行处理,最后将响应数据发送回客户端,并关闭该连接。
给客户端发送信息
Socket服务器的一个基本功能是能够给客户端发送信息,下面是一段实现这一功能的代码:
public void SendMessage(Socket clientSocket, string message)
{
byte[] buffer = Encoding.ASCII.GetBytes(message);
clientSocket.Send(buffer);
}
这段代码接收一个Socket实例和一个发送消息的字符串,然后将该字符串转换为一个字节数组,并将其发送给Socket服务器。
关闭连接
在服务器的处理完成之后,我们需要关闭连接以释放资源,下面的代码提供了关闭连接的实现:
public void CloseClient(Socket clientSocket)
{
try
{
clientSocket.Shutdown(SocketShutdown.Both);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
finally
{
clientSocket.Close();
}
}
这段代码通过调用 Shutdown() 方法来关闭连接,然后使用 Close() 方法来释放所有相关的资源。
下面是一个完整的示例,用C#实现了一个简单的Echo服务器:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace MySocketServer
{
class Program
{
static void Main(string[] args)
{
var server = new SocketServer();
server.Start();
Console.ReadLine();
}
}
public class SocketServer
{
public async void Start()
{
try
{
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 8080));
listener.Listen(5);
Console.WriteLine("Server is listening...");
await AcceptLoop(listener);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public async Task AcceptLoop(Socket listener)
{
while (true)
{
var client = await Task.Factory.FromAsync(listener.BeginAccept, listener.EndAccept, null);
Console.WriteLine("Client connected.");
Task.Factory.StartNew(() => ProcessClient(client));
}
}
public void ProcessClient(Socket clientSocket)
{
try
{
byte[] buffer = new byte[1024];
int length = clientSocket.Receive(buffer);
Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(buffer, 0, length));
string message = Encoding.ASCII.GetString(buffer, 0, length);
SendMessage(clientSocket, message);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
finally
{
CloseClient(clientSocket);
}
}
public void SendMessage(Socket clientSocket, string message)
{
byte[] buffer = Encoding.ASCII.GetBytes(message);
clientSocket.Send(buffer);
}
public void CloseClient(Socket clientSocket)
{
try
{
clientSocket.Shutdown(SocketShutdown.Both);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
finally
{
clientSocket.Close();
}
}
}
}
此示例创建了一个Socket服务器,它监听8080端口,并在客户端连接到它时将任何发送的数据回显回去。当客户端断开连接时,服务器会释放使用的资源。
另外,根据需要,可以根据上述示例自定义指定的端口和消息响应方式,以满足更多的Server需求。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用C#来编写一个异步的Socket服务器 - Python技术站