refactoring, file packet

main
syneffort 2 years ago
parent 08207c9eec
commit 044ace6552
  1. 13
      MySolution/STcpHelper/Packet/ISTcpAsyncPacket.cs
  2. 2
      MySolution/STcpHelper/Packet/PacketType.cs
  3. 16
      MySolution/STcpHelper/Packet/SBufferHelper.cs
  4. 4
      MySolution/STcpHelper/Packet/STcpClientListReqPacket.cs
  5. 14
      MySolution/STcpHelper/Packet/STcpClientListResPacket.cs
  6. 41
      MySolution/STcpHelper/Packet/STcpFileReqPacket.cs
  7. 67
      MySolution/STcpHelper/Packet/STcpFileResPacket.cs
  8. 32
      MySolution/STcpHelper/Packet/STcpPacketHeader.cs
  9. 15
      MySolution/STcpHelper/Packet/STcpTextPacket.cs
  10. 33
      MySolution/STcpHelper/STcpClient.cs
  11. 38
      MySolution/STcpHelper/STcpServer.cs
  12. 2
      MySolution/SerialComApp/SerialCommApp.resx
  13. 7
      MySolution/TAPClient/Program.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace STcpHelper.Packet
{
public interface ISTcpAsyncPacket
{
Task<byte[]> Serialize();
}
}

@ -11,5 +11,7 @@ namespace STcpHelper.Packet
TEXT = 0,
REQ_CLIENT_LIST,
RES_CLIENT_LIST,
REQ_FILE,
RES_FILE,
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
@ -23,5 +24,20 @@ namespace STcpHelper.Packet
return bytes;
}
public static byte[] ConvertPacketTypeToBuffer(PacketType packetType)
{
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)packetType));
}
public static byte[] ConvertDataLengthToBuffer(int dataLength)
{
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(dataLength));
}
public static int ConvertBufferToDataLength(byte[] dataBuffer, int cursor)
{
return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(dataBuffer, cursor));
}
}
}

@ -15,11 +15,9 @@ namespace STcpHelper.Packet
public byte[] Serialize()
{
// 4bytes header
STcpPacketHeader header = new STcpPacketHeader(PacketType.REQ_CLIENT_LIST, 0);
// [header]
return SBufferHelper.GetBuffer(4, header.Serialize());
return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH, header.Serialize());
}
}
}

@ -26,8 +26,8 @@ namespace STcpHelper.Packet
public STcpClientListResPacket(byte[] dataBuffer)
{
int cursor = 0;
short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor));
cursor += sizeof(short);
int length = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(int);
string jsonString = SEncoding.GetString(dataBuffer, cursor, length);
List<string> clients = JsonSerializer.Deserialize<List<string>>(jsonString);
@ -39,13 +39,13 @@ namespace STcpHelper.Packet
{
string jsonString = JsonSerializer.Serialize(this.Clients);
byte[] data = SEncoding.GetBytes(jsonString);
byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length));
byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
// 4bytes header
STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_CLIENT_LIST, dataLength.Length + data.Length);
int dataSize = STcpPacketHeader.GetDataSize(data, dataLength);
// [header][2bytes size][n bytes string]
return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data);
STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_CLIENT_LIST, dataSize);
return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), dataLength, data);
}
}
}

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace STcpHelper.Packet
{
public class STcpFileReqPacket : ISTcpPacket
{
public string Path { get; private set; }
public STcpFileReqPacket(string path)
{
this.Path = path;
}
public STcpFileReqPacket(byte[] dataBuffer)
{
int cursor = 0;
int length = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(int);
this.Path = SEncoding.GetString(dataBuffer, cursor, length);
}
public byte[] Serialize()
{
byte[] data = SEncoding.GetBytes(this.Path);
byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
int dataSize = STcpPacketHeader.GetDataSize(data, dataLength);
STcpPacketHeader header = new STcpPacketHeader(PacketType.REQ_FILE, dataSize);
return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), dataLength, data);
}
}
}

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace STcpHelper.Packet
{
public class STcpFileResPacket : ISTcpAsyncPacket
{
private string _path;
public string FileName { get; private set; }
public byte[] FileBinary { get; private set; }
public STcpFileResPacket(string path)
{
this.FileName = Path.GetFileName(path);
_path = path;
}
public STcpFileResPacket(byte[] dataBuffer, string path)
{
int cursor = 0;
int nameLength = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(int);
this.FileName = SEncoding.GetString(dataBuffer, cursor, nameLength);
cursor += nameLength;
int fileSize = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(int);
this.FileBinary = new byte[fileSize];
Array.Copy(dataBuffer, cursor, this.FileBinary, 0, fileSize);
File.WriteAllBytes(path + @$"\{FileName}", this.FileBinary);
}
public async Task<byte[]> Serialize()
{
byte[] name = SEncoding.GetBytes(this.FileName);
byte[] nameLength = SBufferHelper.ConvertDataLengthToBuffer(name.Length);
byte[] data = await ReadFileAsync(_path);
byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
int dataSize = STcpPacketHeader.GetDataSize(name, nameLength, data, dataLength);
// 4bytes header
STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_FILE, dataSize);
// [heaer][2byte name size][n bytes name][2bytes file size][n bytes string]
return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), nameLength, name, dataLength, data);
}
private async Task<byte[]> ReadFileAsync(string path)
{
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024, useAsync: true))
{
byte[] buffer = new byte[stream.Length];
await stream.ReadAsync(buffer, 0, (int)stream.Length);
return buffer;
}
}
}
}

@ -12,31 +12,45 @@ namespace STcpHelper.Packet
/// </summary>
public class STcpPacketHeader : ISTcpPacket
{
private readonly int TYPE_LENGTH = 4;
public static readonly int HEADER_LENGTH = 8;
public PacketType Type { get; private set; }
public short DataLength { get; private set; }
public int DataLength { get; private set; }
public STcpPacketHeader(PacketType type, int dataLength)
{
Type = type;
DataLength = (short)dataLength;
DataLength = dataLength;
}
public STcpPacketHeader(byte[] buffer)
{
int cursor = 0;
this.Type = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor));
cursor += 2;
this.Type = (PacketType)SBufferHelper.ConvertBufferToDataLength(buffer, cursor);
cursor += TYPE_LENGTH;
this.DataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor));
this.DataLength = SBufferHelper.ConvertBufferToDataLength(buffer, cursor);
}
// [2bytes Type][2bytes Size]
public byte[] Serialize()
{
byte[] type = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)this.Type));
byte[] size = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(this.DataLength));
return SBufferHelper.GetBuffer(type.Length + size.Length, type, size);
byte[] type = SBufferHelper.ConvertPacketTypeToBuffer(this.Type);
byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(this.DataLength);
return SBufferHelper.GetBuffer(HEADER_LENGTH, type, dataLength);
}
public static int GetDataSize(params byte[][] data)
{
int size = 0;
for (int i = 0; i < data.Length; i++)
{
size += data[i].Length;
}
return size;
}
}
}

@ -19,8 +19,8 @@ namespace STcpHelper.Packet
public STcpTextPacket(byte[] dataBuffer)
{
int cursor = 0;
short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor));
cursor += sizeof(short);
int length = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(int);
this.Text = SEncoding.GetString(dataBuffer, cursor, length);
}
@ -28,13 +28,14 @@ namespace STcpHelper.Packet
public byte[] Serialize()
{
byte[] data = SEncoding.GetBytes(Text);
byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length));
byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
// 4bytes header
STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, dataLength.Length + data.Length);
int dataSize = STcpPacketHeader.GetDataSize(data, dataLength);
// [header][2bytes text size][n bytes text]
return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data);
STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, dataSize);
return SBufferHelper.GetBuffer(
STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), dataLength, data);
}
}
}

@ -19,8 +19,10 @@ namespace STcpHelper
private TcpClient _client;
private NetworkStream _stream;
private readonly int HEADER_SIZE = 4;
private readonly int BUFFER_SIZE = 1024;
private readonly int HEADER_SIZE = STcpPacketHeader.HEADER_LENGTH;
// private readonly int BUFFER_SIZE = 1024;
private readonly string FILE_SAVE_FOLDER = @".\";
public async void Connect(string ip, int port)
{
@ -34,7 +36,7 @@ namespace STcpHelper
_ = Task.Run(async () =>
{
byte[] headerBuffer = new byte[HEADER_SIZE];
byte[] dataBuffer = new byte[BUFFER_SIZE];
byte[] dataBuffer;
while (true)
{
Thread.Sleep(50);
@ -42,18 +44,21 @@ namespace STcpHelper
break;
int headerBytesRead = await _stream.ReadAsync(headerBuffer, 0, HEADER_SIZE);
if (headerBytesRead != 4)
if (headerBytesRead != HEADER_SIZE)
{
WriteError(new Exception("Cannot read header"));
return;
}
STcpPacketHeader header = new STcpPacketHeader(headerBuffer);
short dataSize = header.DataLength;
int dataSize = header.DataLength;
dataBuffer = new byte[dataSize];
int totalRecv = 0;
while (totalRecv < dataSize)
{
int dataBytesRead = await _stream.ReadAsync(dataBuffer, totalRecv, dataSize - totalRecv);
totalRecv += dataBytesRead;
}
@ -70,6 +75,11 @@ namespace STcpHelper
WriteMessage(client);
}
}
else if (header.Type == PacketType.RES_FILE)
{
STcpFileResPacket packet = new STcpFileResPacket(dataBuffer, FILE_SAVE_FOLDER);
WriteMessage($"File({packet.FileName}) saved.");
}
}
}, _cts.Token);
}
@ -111,6 +121,19 @@ namespace STcpHelper
}
}
public async void RequireFile(string path)
{
try
{
STcpFileReqPacket packet = new STcpFileReqPacket(path);
await _stream.WriteAsync(packet.Serialize());
}
catch (Exception ex)
{
WriteError(ex);
}
}
public void Close()
{
try

@ -11,7 +11,7 @@ namespace STcpHelper
private List<TcpClient> _clients;
private readonly int HEADER_SIZE = 4;
private readonly int HEADER_SIZE = STcpPacketHeader.HEADER_LENGTH;
private readonly int BUFFER_SIZE;
private int _port;
@ -56,14 +56,14 @@ namespace STcpHelper
while (true)
{
int headerBytesRead = await stream.ReadAsync(headerBuffer, 0, HEADER_SIZE);
if (headerBytesRead != 4)
if (headerBytesRead != HEADER_SIZE)
{
WriteError(new Exception("Cannot read header"));
return;
}
STcpPacketHeader header = new STcpPacketHeader(headerBuffer);
short dataSize = header.DataLength;
int dataSize = header.DataLength;
int totalRecv = 0;
while (totalRecv < dataSize)
{
@ -71,10 +71,11 @@ namespace STcpHelper
totalRecv += dataBytesRead;
}
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
if (header.Type == PacketType.TEXT)
{
STcpTextPacket packet = new STcpTextPacket(dataBuffer);
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
// Broadcast
BroadcastMessage(packet.Text, client);
@ -83,11 +84,18 @@ namespace STcpHelper
else if (header.Type == PacketType.REQ_CLIENT_LIST)
{
STcpClientListResPacket packet = new STcpClientListResPacket(_clients);
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
// Send
SendPacket(packet, client);
}
else if (header.Type == PacketType.REQ_FILE)
{
STcpFileReqPacket recvPacket = new STcpFileReqPacket(dataBuffer);
STcpFileResPacket packet = new STcpFileResPacket(recvPacket.Path);
// Send async
SendAsyncPacket(packet, client);
}
if (!IsClientConnected(client))
break;
@ -123,6 +131,26 @@ namespace STcpHelper
if (!IsClientConnected(requester))
return;
if (responseByte.Length < BUFFER_SIZE)
requester.GetStream().WriteAsync(responseByte, 0, responseByte.Length);
else
{
int totalSend = 0;
while (totalSend < responseByte.Length)
{
int sendCount = responseByte.Length - totalSend < BUFFER_SIZE ? responseByte.Length - totalSend : BUFFER_SIZE;
requester.GetStream().WriteAsync(responseByte, totalSend, sendCount);
totalSend += sendCount;
}
}
}
private async void SendAsyncPacket(ISTcpAsyncPacket packet, TcpClient requester)
{
byte[] responseByte = await packet.Serialize();
if (!IsClientConnected(requester))
return;
requester.GetStream().WriteAsync(responseByte, 0, responseByte.Length);
}

@ -121,7 +121,7 @@
<data name="portRefreshButton.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
DgAACw4BQL7hQQAAAsBJREFUaEPt2cnLTXEcx/FrzJCphJ0F2diIbEQokWFnzhClyFB6yEJEyh+gUMaU
DQAACw0B7QfALAAAAsBJREFUaEPt2cnLTXEcx/FrzJCphJ0F2diIbEQokWFnzhClyFB6yEJEyh+gUMaU
WdlYWLBRiszjAmFjaUgZMvP+LE6dTp9z7jnnnt990PnUa/N07+/7u/ee3/g06tSpU+efzihswFncxzt8
x1e8xm0cx2oMx1+R7liOG/hdwC9cxXx0Q6dkNp7DdbCIh5iKtqUvjsF1piz9InvQE0EzDPfgOlGFKxiE
IBmKZ3CF03zBt8TfmrmFAag0fXAXrmCcXrMd4zAYUYZgInbjCdx74y6h0sF9BK5QRANxJvKkKxaj2QSw

@ -16,9 +16,16 @@ namespace TAPClient
string input = Console.ReadLine();
switch (input.ToLower())
{
case "":
break;
case "rcl":
client.RequireClientList();
break;
case "df":
Console.Write("File path: ");
string path = Console.ReadLine();
client.RequireFile(path);
break;
default:
client.SendMessage(input);
break;

Loading…
Cancel
Save