C  Socket使用以及DotNetty和Supersocket 框架

C# Socket

C#中Socket是一种与操作系统IOCP(Input/Output Completion Ports,IO 操作完成端口)机制相关的API,Socket实例作为操作的重要载体之一,向上提供了多种访问层,不仅能够与TCP类型的socket进行交互,还可以与UDP类型的socket进行交互,操作也十分灵活方便。

使用Socket进行网络编程,主要分为服务端和客户端两种情况,下面将分别对这两种情况进行介绍。

服务端示例:

```csharp

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

namespace Server

{

class Program

{

static void Main(string[] args)

{

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

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

serverSocket.Bind(ipEndPoint);

serverSocket.Listen(10);

Console.WriteLine("服务器已启动:{0}", serverSocket.LocalEndPoint.ToString());

while (true)

{

Socket clientSocket = serverSocket.Accept();

byte[] buffer = new byte[1024];

int length = clientSocket.Receive(buffer);

Console.WriteLine("接收到客户端消息:{0}", Encoding.ASCII.GetString(buffer, 0, length));

clientSocket.Send(Encoding.ASCII.GetBytes("服务端已接收到消息"));

clientSocket.Close();

}

}

}

}

```

客户端示例:

```csharp

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

namespace Client

{

class Program

{

static void Main(string[] args)

{

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

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

clientSocket.Connect(ipEndPoint);

string message = "Hello, Server!";

clientSocket.Send(Encoding.ASCII.GetBytes(message));

byte[] buffer = new byte[1024];

int length = clientSocket.Receive(buffer);

Console.WriteLine("接收到服务器消息:{0}", Encoding.ASCII.GetString(buffer, 0, length));

clientSocket.Close();

}

}

}

```

在这里,服务端使用的是Socket.Bind方法绑定IP地址和端口,并进入监听状态;客户端使用的是Socket.Connect方法连接到服务端。

DotNetty

DotNetty是基于C#开发的网络框架,使用了高度优化的异步IO和高效的消息编码机制,可以轻松实现高性能、高吞吐率的网络应用程序。

使用DotNetty进行网络编程,同样需要分为服务端和客户端两种情况。

服务端示例:

```csharp

using System;

using System.Text;

using System.Threading.Tasks;

using DotNetty.Buffers;

using DotNetty.Common.Concurrency;

using DotNetty.Transport.Bootstrapping;

using DotNetty.Transport.Channels;

using DotNetty.Transport.Channels.Sockets;

namespace Server

{

class Program

{

static async Task Main(string[] args)

{

IEventLoopGroup bossGroup = new MultithreadEventLoopGroup(1);

IEventLoopGroup workGroup = new MultithreadEventLoopGroup();

try

{

ServerBootstrap bootstrap = new ServerBootstrap();

bootstrap.Group(bossGroup, workGroup)

.Channel()

.Option(ChannelOption.SoBacklog, 100)

.Handler(new LoggingHandler("SRV-LSTN"))

.ChildHandler(new ActionChannelInitializer(channel =>

{

IChannelPipeline pipeline = channel.Pipeline;

pipeline.AddLast(new LoggingHandler("SRV-CNCT"));

pipeline.AddLast(new SimpleServerHandler());

}));

IChannel boundChannel = await bootstrap.BindAsync(5000);

Console.WriteLine("服务端已启动:{0}", boundChannel.LocalAddress);

await boundChannel.CloseAsync();

}

finally

{

await Task.WhenAll(

bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),

workGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))

);

}

}

}

public class SimpleServerHandler : ChannelHandlerAdapter

{

public override void ChannelRead(IChannelHandlerContext context, object message)

{

IByteBuffer buffer = message as IByteBuffer;

Console.WriteLine("接收到客户端消息:{0}", buffer.ToString(Encoding.ASCII));

context.WriteAsync(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("服务端已接收到消息")));

}

public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)

{

Console.WriteLine("出现异常:{0}", exception);

context.CloseAsync();

}

}

}

```

客户端示例:

```csharp

using System;

using System.Text;

using System.Threading.Tasks;

using DotNetty.Buffers;

using DotNetty.Common.Concurrency;

using DotNetty.Transport.Bootstrapping;

using DotNetty.Transport.Channels;

using DotNetty.Transport.Channels.Sockets;

namespace Client

{

class Program

{

static async Task Main(string[] args)

{

IEventLoopGroup group = new MultithreadEventLoopGroup();

try

{

Bootstrap bootstrap = new Bootstrap();

bootstrap.Group(group)

.Channel()

.Option(ChannelOption.SoKeepalive, true)

.Handler(new SimpleClientHandler());

IChannel channel = await bootstrap.ConnectAsync("127.0.0.1", 5000);

Console.WriteLine("连接服务器成功:{0}", channel.LocalAddress);

string message = "Hello, Server!";

IByteBuffer buffer = Unpooled.Buffer(Encoding.ASCII.GetBytes(message).Length);

buffer.WriteString(message);

await channel.WriteAndFlushAsync(buffer);

await channel.CloseAsync();

}

finally

{

await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));

}

}

}

public class SimpleClientHandler : ChannelHandlerAdapter

{

public override void ChannelRead(IChannelHandlerContext context, object message)

{

IByteBuffer buffer = message as IByteBuffer;

Console.WriteLine("接收到服务器消息:{0}", buffer.ToString(Encoding.ASCII));

context.CloseAsync();

}

public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)

{

Console.WriteLine("出现异常:{0}", exception);

context.CloseAsync();

}

}

}

```

在这里,服务端使用的是EventLoop和ChannelPipeline提供的机制,创建了一个SimpleServerHandler类进行消息处理;客户端同样使用的是EventLoop和ChannelPipeline提供的机制,创建了一个SimpleClientHandler类进行消息处理。

Supersocket

Supersocket是一个基于C#的轻量级网络应用框架,提供了TCP和UDP等基于Socket的通信方式,并支持复杂的通讯协议的开发。Supersocket通过IAppSession和IAppServer两个核心接口来完成服务端的开发,遵循了典型的工厂模式和责任链模式。

Supersocket服务端示例:

```csharp

using System.Text;

using SuperSocket;

using SuperSocket.Command;

using SuperSocket.ProtoBase;

using SuperSocket.Server;

namespace Server

{

class Program

{

static void Main(string[] args)

{

var hostConfig = new SuperSocketHostBuilder()

.ConfigureSuperSocket(options =>

{

options.Name = "SuperSocket";

options.Listeners = new[]

{

new ListenOptions

{

Ip = "Any",

BackLog = 100,

Port = 5000

}

};

})

.UseCommand("MyCommand")

.UsePackageHandler(async (s, p) =>

{

await s.SendAsync(Encoding.ASCII.GetBytes("服务端已接收到消息"));

})

.Build();

hostConfig.Start();

Console.WriteLine("服务端已启动:{0}", hostConfig.IsRunning);

Console.Read();

}

}

public class MyCommand : IAsyncCommand

{

public async ValueTask ExecuteAsync(IAppSession session, StringPackageInfo package)

{

Console.WriteLine("接收到客户端消息:{0}", package.Body);

await session.SendAsync(Encoding.ASCII.GetBytes("服务端已接收到命令"));

}

}

public class AppSession : AppSession

{

}

}

```

通过SuperSocketHostBuilder和SuperSocket内置的一些组件,可以快速解决服务端编程中的许多问题。

Supersocket客户端示例:

```csharp

using System.Text;

using SuperSocket.Client;

namespace Client

{

class Program

{

static async Task Main(string[] args)

{

var client = new EasyClient();

client.Initialize(new CommandLinePipelineFilter());

await client.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000));

Console.WriteLine("连接服务器成功:{0}", client.IsConnected);

string message = "MyCommand|Hello, Server!";

StringPackageInfo package = new StringPackageInfo(message, Encoding.ASCII.GetBytes(message));

await client.SendAsync(package);

Console.WriteLine("接收到服务器消息:{0}", Encoding.ASCII.GetString(await client.ReceiveAsync()));

}

}

}

```

通过EasyClient和CommandLinePipelineFilter等SuperSocket组件,可以实现快速的客户端编程。在这里,我们使用了CommandLinePipelineFilter,可以将输入的命令解析成StringPackageInfo,然后通过EasyClient.SendAsync方法将StringPackageInfo发送给服务器,最后通过EasyClient.ReceiveAsync方法接收服务器返回的消息。

结语

以上是C#应用网络编程的三种方式,并提供了各自的示例程序,这使得大家能够快速入门,并理解各自的使用方式。其中,C# Socket 是C#中最基础和底层的方式,理解了它的机制,才能更加深入其它两种形式的网络编程,适合需要对网络编程进行深入研究的开发者;DotNetty 是基于C#的高性能网络框架,适合需要高性能网络服务的开发者;SuperSocket 是基于C#的网络应用框架,适合需要复杂协议和自定义规则的网络编程开发者。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(104) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部