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, TEXT = 0,
REQ_CLIENT_LIST, REQ_CLIENT_LIST,
RES_CLIENT_LIST, RES_CLIENT_LIST,
REQ_FILE,
RES_FILE,
} }
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -23,5 +24,20 @@ namespace STcpHelper.Packet
return bytes; 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() public byte[] Serialize()
{ {
// 4bytes header
STcpPacketHeader header = new STcpPacketHeader(PacketType.REQ_CLIENT_LIST, 0); STcpPacketHeader header = new STcpPacketHeader(PacketType.REQ_CLIENT_LIST, 0);
// [header] return SBufferHelper.GetBuffer(STcpPacketHeader.HEADER_LENGTH, header.Serialize());
return SBufferHelper.GetBuffer(4, header.Serialize());
} }
} }
} }

@ -26,8 +26,8 @@ namespace STcpHelper.Packet
public STcpClientListResPacket(byte[] dataBuffer) public STcpClientListResPacket(byte[] dataBuffer)
{ {
int cursor = 0; int cursor = 0;
short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor)); int length = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(short); cursor += sizeof(int);
string jsonString = SEncoding.GetString(dataBuffer, cursor, length); string jsonString = SEncoding.GetString(dataBuffer, cursor, length);
List<string> clients = JsonSerializer.Deserialize<List<string>>(jsonString); List<string> clients = JsonSerializer.Deserialize<List<string>>(jsonString);
@ -39,13 +39,13 @@ namespace STcpHelper.Packet
{ {
string jsonString = JsonSerializer.Serialize(this.Clients); string jsonString = JsonSerializer.Serialize(this.Clients);
byte[] data = SEncoding.GetBytes(jsonString); byte[] data = SEncoding.GetBytes(jsonString);
byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length)); byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
// 4bytes header int dataSize = STcpPacketHeader.GetDataSize(data, dataLength);
STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_CLIENT_LIST, dataLength.Length + data.Length);
// [header][2bytes size][n bytes string] STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_CLIENT_LIST, dataSize);
return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data);
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> /// </summary>
public class STcpPacketHeader : ISTcpPacket public class STcpPacketHeader : ISTcpPacket
{ {
private readonly int TYPE_LENGTH = 4;
public static readonly int HEADER_LENGTH = 8;
public PacketType Type { get; private set; } public PacketType Type { get; private set; }
public short DataLength { get; private set; } public int DataLength { get; private set; }
public STcpPacketHeader(PacketType type, int dataLength) public STcpPacketHeader(PacketType type, int dataLength)
{ {
Type = type; Type = type;
DataLength = (short)dataLength; DataLength = dataLength;
} }
public STcpPacketHeader(byte[] buffer) public STcpPacketHeader(byte[] buffer)
{ {
int cursor = 0; int cursor = 0;
this.Type = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor)); this.Type = (PacketType)SBufferHelper.ConvertBufferToDataLength(buffer, cursor);
cursor += 2; cursor += TYPE_LENGTH;
this.DataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor)); this.DataLength = SBufferHelper.ConvertBufferToDataLength(buffer, cursor);
} }
// [2bytes Type][2bytes Size]
public byte[] Serialize() 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) public STcpTextPacket(byte[] dataBuffer)
{ {
int cursor = 0; int cursor = 0;
short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor)); int length = SBufferHelper.ConvertBufferToDataLength(dataBuffer, cursor);
cursor += sizeof(short); cursor += sizeof(int);
this.Text = SEncoding.GetString(dataBuffer, cursor, length); this.Text = SEncoding.GetString(dataBuffer, cursor, length);
} }
@ -28,13 +28,14 @@ namespace STcpHelper.Packet
public byte[] Serialize() public byte[] Serialize()
{ {
byte[] data = SEncoding.GetBytes(Text); byte[] data = SEncoding.GetBytes(Text);
byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length)); byte[] dataLength = SBufferHelper.ConvertDataLengthToBuffer(data.Length);
// 4bytes header int dataSize = STcpPacketHeader.GetDataSize(data, dataLength);
STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, dataLength.Length + data.Length);
// [header][2bytes text size][n bytes text] STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, dataSize);
return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data);
return SBufferHelper.GetBuffer(
STcpPacketHeader.HEADER_LENGTH + dataSize, header.Serialize(), dataLength, data);
} }
} }
} }

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

@ -11,7 +11,7 @@ namespace STcpHelper
private List<TcpClient> _clients; private List<TcpClient> _clients;
private readonly int HEADER_SIZE = 4; private readonly int HEADER_SIZE = STcpPacketHeader.HEADER_LENGTH;
private readonly int BUFFER_SIZE; private readonly int BUFFER_SIZE;
private int _port; private int _port;
@ -56,14 +56,14 @@ namespace STcpHelper
while (true) while (true)
{ {
int headerBytesRead = await stream.ReadAsync(headerBuffer, 0, HEADER_SIZE); int headerBytesRead = await stream.ReadAsync(headerBuffer, 0, HEADER_SIZE);
if (headerBytesRead != 4) if (headerBytesRead != HEADER_SIZE)
{ {
WriteError(new Exception("Cannot read header")); WriteError(new Exception("Cannot read header"));
return; return;
} }
STcpPacketHeader header = new STcpPacketHeader(headerBuffer); STcpPacketHeader header = new STcpPacketHeader(headerBuffer);
short dataSize = header.DataLength; int dataSize = header.DataLength;
int totalRecv = 0; int totalRecv = 0;
while (totalRecv < dataSize) while (totalRecv < dataSize)
{ {
@ -71,10 +71,11 @@ namespace STcpHelper
totalRecv += dataBytesRead; totalRecv += dataBytesRead;
} }
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
if (header.Type == PacketType.TEXT) if (header.Type == PacketType.TEXT)
{ {
STcpTextPacket packet = new STcpTextPacket(dataBuffer); STcpTextPacket packet = new STcpTextPacket(dataBuffer);
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
// Broadcast // Broadcast
BroadcastMessage(packet.Text, client); BroadcastMessage(packet.Text, client);
@ -83,11 +84,18 @@ namespace STcpHelper
else if (header.Type == PacketType.REQ_CLIENT_LIST) else if (header.Type == PacketType.REQ_CLIENT_LIST)
{ {
STcpClientListResPacket packet = new STcpClientListResPacket(_clients); STcpClientListResPacket packet = new STcpClientListResPacket(_clients);
WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}");
// Send // Send
SendPacket(packet, client); 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)) if (!IsClientConnected(client))
break; break;
@ -123,6 +131,26 @@ namespace STcpHelper
if (!IsClientConnected(requester)) if (!IsClientConnected(requester))
return; 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); 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"> <data name="portRefreshButton.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
DgAACw4BQL7hQQAAAsBJREFUaEPt2cnLTXEcx/FrzJCphJ0F2diIbEQokWFnzhClyFB6yEJEyh+gUMaU DQAACw0B7QfALAAAAsBJREFUaEPt2cnLTXEcx/FrzJCphJ0F2diIbEQokWFnzhClyFB6yEJEyh+gUMaU
WdlYWLBRiszjAmFjaUgZMvP+LE6dTp9z7jnnnt990PnUa/N07+/7u/ee3/g06tSpU+efzihswFncxzt8 WdlYWLBRiszjAmFjaUgZMvP+LE6dTp9z7jnnnt990PnUa/N07+/7u/ee3/g06tSpU+efzihswFncxzt8
x1e8xm0cx2oMx1+R7liOG/hdwC9cxXx0Q6dkNp7DdbCIh5iKtqUvjsF1piz9InvQE0EzDPfgOlGFKxiE x1e8xm0cx2oMx1+R7liOG/hdwC9cxXx0Q6dkNp7DdbCIh5iKtqUvjsF1piz9InvQE0EzDPfgOlGFKxiE
IBmKZ3CF03zBt8TfmrmFAag0fXAXrmCcXrMd4zAYUYZgInbjCdx74y6h0sF9BK5QRANxJvKkKxaj2QSw IBmKZ3CF03zBt8TfmrmFAag0fXAXrmCcXrMd4zAYUYZgInbjCdx74y6h0sF9BK5QRANxJvKkKxaj2QSw

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

Loading…
Cancel
Save