Skip to content

Commit

Permalink
网络库发送逻辑使用IPacket,部分代码尚未完整,特别是链式包和chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Sep 2, 2024
1 parent 913c8e6 commit d6356dd
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 30 deletions.
18 changes: 18 additions & 0 deletions NewLife.Core/Data/IPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ public static Stream GetStream(this IPacket pk)

return new MemoryStream(pk.GetSpan().ToArray());
}

/// <summary>返回数据段集合</summary>
/// <returns></returns>
public static IList<ArraySegment<Byte>> ToSegments(this IPacket pk)
{
// 初始4元素,优化扩容
var list = new List<ArraySegment<Byte>>(4);

for (var p = pk; p != null; p = p.Next)
{
if (p is ArrayPacket ap)
list.Add(new ArraySegment<Byte>(ap.Buffer, ap.Offset, ap.Length));
else
list.Add(new ArraySegment<Byte>(p.GetSpan().ToArray(), 0, p.Length));
}

return list;
}
}

/// <summary>所有权内存包。具有所有权管理,不再使用时释放</summary>
Expand Down
54 changes: 54 additions & 0 deletions NewLife.Core/Extension/SpanHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,58 @@ public static Task WriteAsync(this Stream stream, ReadOnlyMemory<Byte> buffer, C
}
});
}

#if NETFRAMEWORK || NETSTANDARD
/// <summary>去掉前后字符</summary>
/// <typeparam name="T"></typeparam>
/// <param name="span"></param>
/// <param name="trimElement"></param>
/// <returns></returns>
public static ReadOnlySpan<T> Trim<T>(this ReadOnlySpan<T> span, T trimElement) where T : IEquatable<T>
{
var start = ClampStart(span, trimElement);
var length = ClampEnd(span, start, trimElement);
return span.Slice(start, length);
}

/// <summary>去掉前后字符</summary>
/// <typeparam name="T"></typeparam>
/// <param name="span"></param>
/// <param name="trimElement"></param>
/// <returns></returns>
public static Span<T> Trim<T>(this Span<T> span, T trimElement) where T : IEquatable<T>
{
var start = ClampStart(span, trimElement);
var length = ClampEnd(span, start, trimElement);
return span.Slice(start, length);
}

private static Int32 ClampStart<T>(ReadOnlySpan<T> span, T trimElement) where T : IEquatable<T>
{
var i = 0;
for (; i < span.Length; i++)
{
ref var reference = ref trimElement;
if (!reference.Equals(span[i]))
{
break;
}
}
return i;
}
private static Int32 ClampEnd<T>(ReadOnlySpan<T> span, Int32 start, T trimElement) where T : IEquatable<T>
{
var num = span.Length - 1;
while (num >= start)
{
ref var reference = ref trimElement;
if (!reference.Equals(span[num]))
{
break;
}
num--;
}
return num - start + 1;
}
#endif
}
9 changes: 5 additions & 4 deletions NewLife.Core/Http/HttpBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System;
using System.Text;
using NewLife.Collections;
using NewLife.Data;
using NewLife.Serialization;
Expand Down Expand Up @@ -78,8 +79,8 @@ public Boolean Parse(IPacket pk)
var p3 = line.IndexOf((Byte)':');
if (p3 > 0)
{
var name = line[..p3].ToStr();
var value = line[(p3 + 1)..].ToStr();
var name = line[..p3].Trim((Byte)' ').ToStr();
var value = line[(p3 + 1)..].Trim((Byte)' ').ToStr();
Headers[name] = value;
}
}
Expand Down Expand Up @@ -122,7 +123,7 @@ public Boolean Parse(IPacket pk)
public virtual IPacket Build()
{
var body = Body;
var len = body != null ? body.Length : -1;
var len = body != null ? body.Length : 0;

var header = BuildHeader(len);
var pk = new ArrayPacket(Encoding.UTF8.GetByteCount(header) + len);
Expand Down
3 changes: 3 additions & 0 deletions NewLife.Core/Http/WebSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public void Process(IPacket pk)

Handler?.Invoke(this, message);

// 释放内存
message.Payload?.TryDispose();

var session = Context?.Connection;
var socket = Context?.Socket;
if (session == null && socket == null) return;
Expand Down
20 changes: 17 additions & 3 deletions NewLife.Core/Net/ISocketRemote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface ISocketRemote : ISocket, IExtend
/// </remarks>
/// <param name="data">数据包</param>
/// <returns>是否成功</returns>
Int32 Send(Packet data);
Int32 Send(IPacket data);
#endregion

#region 接收
Expand Down Expand Up @@ -69,6 +69,20 @@ public interface ISocketRemote : ISocket, IExtend
public static class SocketRemoteHelper
{
#region 发送
/// <summary>发送数组</summary>
/// <param name="session"></param>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <returns></returns>
public static Int32 Send(this ISocketRemote session, Byte[] buffer, Int32 offset = 0, Int32 count = -1)
{
if (count < 0) count = buffer.Length - offset;
var pk = new ArrayPacket(buffer, offset, count);

return session.Send(pk);
}

/// <summary>发送数据流</summary>
/// <param name="session">会话</param>
/// <param name="stream">数据流</param>
Expand All @@ -86,7 +100,7 @@ public static Int32 Send(this ISocketRemote session, Stream stream)
var count = stream.Read(buffer, 0, buffer.Length);
if (count <= 0) break;

var pk = new Packet(buffer, 0, count);
var pk = new ArrayPacket(buffer, 0, count);
var count2 = session.Send(pk);
if (count2 < 0) break;
rs += count2;
Expand Down Expand Up @@ -158,7 +172,7 @@ public static Int32 SendMessages(this ISocketRemote session, Stream stream)
if (rs <= 0) break;

// 打包数据,标准编码器StandardCodec将会在头部加上4字节头部,交给下层Tcp发出
var pk = new Packet(buffer, 0, rs);
var pk = new ArrayPacket(buffer, 0, rs);
session.SendMessage(pk);

count++;
Expand Down
2 changes: 1 addition & 1 deletion NewLife.Core/Net/ITransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface ITransport : IDisposable

/// <summary>写入数据</summary>
/// <param name="data">数据包</param>
Int32 Send(Packet data);
Int32 Send(IPacket data);

/// <summary>读取数据</summary>
/// <returns></returns>
Expand Down
3 changes: 2 additions & 1 deletion NewLife.Core/Net/NetHandlerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,12 @@ public override Int32 FireWrite(Object message)
// 发送一包数据
if (message is Byte[] buf) return session.Send(buf);
if (message is Packet pk) return session.Send(pk);
if (message is IPacket ip) return session.Send(ip);
if (message is String str) return session.Send(str.GetBytes());
if (message is IAccessor acc) return session.Send(acc.ToPacket());

// 发送一批数据包
if (message is IEnumerable<Packet> pks)
if (message is IEnumerable<IPacket> pks)
{
var rs = 0;
foreach (var item in pks)
Expand Down
4 changes: 2 additions & 2 deletions NewLife.Core/Net/SessionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public virtual Boolean Close(String reason)
/// </remarks>
/// <param name="data">数据包</param>
/// <returns>是否成功</returns>
public Int32 Send(Packet data)
public Int32 Send(IPacket data)
{
if (Disposed) throw new ObjectDisposedException(GetType().Name);
if (!Open()) return -1;
Expand All @@ -254,7 +254,7 @@ public Int32 Send(Packet data)
/// </remarks>
/// <param name="data">数据包</param>
/// <returns>是否成功</returns>
protected abstract Int32 OnSend(Packet data);
protected abstract Int32 OnSend(IPacket data);

#endregion 发送

Expand Down
23 changes: 16 additions & 7 deletions NewLife.Core/Net/TcpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,14 @@ protected override Boolean OnClose(String reason)
/// </remarks>
/// <param name="pk">数据包</param>
/// <returns>是否成功</returns>
protected override Int32 OnSend(Packet pk)
protected override Int32 OnSend(IPacket pk)
{
var count = pk.Total;
var count = pk.Length;
var data = pk.GetSpan();

if (Log != null && Log.Enable && LogSend) WriteLog("Send [{0}]: {1}", count, pk.ToHex(LogDataLength));
if (Log != null && Log.Enable && LogSend) WriteLog("Send [{0}]: {1}", count, data.ToHex(LogDataLength));

using var span = Tracer?.NewSpan($"net:{Name}:Send", pk.Total + "", pk.Total);
using var span = Tracer?.NewSpan($"net:{Name}:Send", count + "", count);

var rs = count;
var sock = Client;
Expand All @@ -318,7 +319,11 @@ protected override Int32 OnSend(Packet pk)
if (count == 0)
rs = sock.Send(Pool.Empty);
else if (pk.Next == null)
rs = sock.Send(pk.Data, pk.Offset, count, SocketFlags.None);
#if NETCOREAPP || NETSTANDARD2_1
rs = sock.Send(data);
#else
rs = sock.Send(data.ToArray(), count, SocketFlags.None);
#endif
else
rs = sock.Send(pk.ToSegments());
}
Expand All @@ -327,9 +332,13 @@ protected override Int32 OnSend(Packet pk)
if (count == 0)
_Stream.Write([]);
else if (pk.Next == null)
_Stream.Write(pk.Data, pk.Offset, count);
#if NETCOREAPP || NETSTANDARD2_1
_Stream.Write(data);
#else
_Stream.Write(data.ToArray());
#endif
else
_Stream.Write(pk.ToArray());
pk.CopyTo(_Stream);
}

//// 检查返回值
Expand Down
29 changes: 19 additions & 10 deletions NewLife.Core/Net/UdpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected override Boolean OnClose(String reason)
var remote = Remote;
if (remote != null && !remote.Address.IsAny() && remote.Port != 0)
{
Send(Pool.Empty);
this.Send(Pool.Empty);
}

Client = null;
Expand Down Expand Up @@ -145,13 +145,14 @@ protected override Boolean OnClose(String reason)
/// </remarks>
/// <param name="pk">数据包</param>
/// <returns>是否成功</returns>
protected override Int32 OnSend(Packet pk) => OnSend(pk, Remote.EndPoint);
protected override Int32 OnSend(IPacket pk) => OnSend(pk, Remote.EndPoint);

internal Int32 OnSend(Packet pk, IPEndPoint remote)
internal Int32 OnSend(IPacket pk, IPEndPoint remote)
{
var count = pk.Total;
var count = pk.Length;
var data = pk.GetSpan();

using var span = Tracer?.NewSpan($"net:{Name}:Send", pk.Total + "", pk.Total);
using var span = Tracer?.NewSpan($"net:{Name}:Send", count + "", count);

try
{
Expand All @@ -161,22 +162,30 @@ internal Int32 OnSend(Packet pk, IPEndPoint remote)
{
if (sock.Connected && !sock.EnableBroadcast)
{
if (Log.Enable && LogSend) WriteLog("Send [{0}]: {1}", count, pk.ToHex(LogDataLength));
if (Log.Enable && LogSend) WriteLog("Send [{0}]: {1}", count, data.ToHex(LogDataLength));

if (pk.Next == null)
rs = sock.Send(pk.Data, pk.Offset, count, SocketFlags.None);
#if NETCOREAPP || NETSTANDARD2_1
rs = sock.Send(data);
#else
rs = sock.Send(data.ToArray(), count, SocketFlags.None);
#endif
else
rs = sock.Send(pk.ToSegments(), SocketFlags.None);
}
else
{
sock.CheckBroadcast(remote.Address);
if (Log.Enable && LogSend) WriteLog("Send {2} [{0}]: {1}", count, pk.ToHex(LogDataLength), remote);
if (Log.Enable && LogSend) WriteLog("Send {2} [{0}]: {1}", count, data.ToHex(LogDataLength), remote);

if (pk.Next == null)
rs = sock.SendTo(pk.Data, pk.Offset, count, SocketFlags.None, remote);
#if NET6_0_OR_GREATER
rs = sock.SendTo(data, remote);
#else
rs = sock.SendTo(data.ToArray(), 0, count, SocketFlags.None, remote);
#endif
else
rs = sock.SendTo(pk.ToArray(), 0, count, SocketFlags.None, remote);
rs = sock.SendTo(data.ToArray(), 0, count, SocketFlags.None, remote);
}
}

Expand Down
2 changes: 1 addition & 1 deletion NewLife.Core/Net/UdpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ protected override void Dispose(Boolean disposing)
/// <param name="data"></param>
/// <returns></returns>
/// <exception cref="ObjectDisposedException"></exception>
public Int32 Send(Packet data)
public Int32 Send(IPacket data)
{
if (Disposed) throw new ObjectDisposedException(GetType().Name);

Expand Down
1 change: 1 addition & 0 deletions Samples/Zero.Server/ClientTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Net.Sockets;
using System.Text;
using NewLife;
using NewLife.Data;
using NewLife.Log;
using NewLife.Net;

Expand Down
2 changes: 1 addition & 1 deletion XUnitTest.Core/Http/HttpServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void ProcessRequest(IHttpContext context)

// 数据部分,链式
var pk = context.Request.Body;
Assert.Equal(8 * 1024 * 2, pk.Total);
Assert.Equal(8 * 1024 * 2, pk.Length);

var name = context.Parameters["name"];
var html = $"<h2>你好,<span color=\"red\">{name}</span></h2>";
Expand Down
1 change: 1 addition & 0 deletions XUnitTest.Core/Http/TinyHttpClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using NewLife.Http;
using NewLife.Log;
using Xunit;
using NewLife.Data;

namespace XUnitTest.Http;

Expand Down

0 comments on commit d6356dd

Please sign in to comment.