Skip to content

Commit

Permalink
Доделываю логику TCP (Упаковки и распаковки)
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkRen committed May 2, 2024
1 parent 05fcdc5 commit c90c9f1
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 51 deletions.
7 changes: 5 additions & 2 deletions LauncherDM/Services/LoadingWindowService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ public bool CheckRequestServer()
if (serverRequest is null)
serverRequest = new ServerRequestService();

var requestMessageServer = serverRequest.SendMessageRequest(MessageHeader.MessageType.Check);
return requestMessageServer.Message == "1";
//var requestMessageServer = serverRequest.SendMessageRequest(MessageHeader.MessageType.Check);
//return requestMessageServer.Message == "1";

var a = serverRequest.SendMessageRequest(MessageHeader.MessageType.Token);
return false;
}

public string GetTitle()
Expand Down
9 changes: 2 additions & 7 deletions LauncherDM/Services/ServerRequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,8 @@ public MessageHeader SendMessageRequest(MessageHeader.MessageType messageType)
do
{
byte[] getBytes = new byte[tcpClient.ReceiveBufferSize];
tcpStream.Read(getBytes, 0, tcpClient.ReceiveBufferSize);
var defaultData = getBytes.Skip(1).Take(5);
var size = 0;
foreach (var sizeData in defaultData)
size += sizeData;
getBytes = getBytes.Take(size + MessageHeader.LengthAndDataType).ToArray();
return MessageHeader.FromArray(getBytes);
var lengthByte = tcpStream.Read(getBytes, 0, tcpClient.ReceiveBufferSize);
return MessageHeader.FromArray(getBytes.Take(lengthByte).ToArray());
} while (tcpStream.DataAvailable);
}
}
Expand Down
147 changes: 136 additions & 11 deletions ServerTCP/MessageHeader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Buffers.Binary;
using ServerTCP.DataBase;
using ServerTCP.Models;
using System.Buffers.Binary;
using System.Text;

namespace ServerTCP
Expand All @@ -9,6 +11,7 @@ namespace ServerTCP
public class MessageHeader
{
public const int LengthAndDataType = 6; // 1 байт тип данных, 5 байт размер
public const int TokenLength = 10; // 10 байт под токен

public enum MessageType : byte
{
Expand Down Expand Up @@ -39,9 +42,20 @@ public enum Languages
public object Message { get; }
public string Token { get; }

public MessageHeader(MessageType type, int length)
public MessageHeader(MessageType type, Languages lang, string token, int length)
{
Type = type;
Language = lang;
Token = token;
Length = length;
}

public MessageHeader(object message, MessageType type, Languages lang, string token, int length)
{
Message = message;
Type = type;
Language = lang;
Token = token;
Length = length;
}

Expand All @@ -52,22 +66,95 @@ public MessageHeader(object message, MessageType type, int length)
Length = length;
}

public byte[] MessageToArray()
public MessageHeader(MessageType type, Languages lang, int length = 0)
{
Type = type;
Language = lang;
Length = length;
}

public MessageHeader(MessageType type, int length = 0)
{
Type = type;
Length = length;
}

/// <summary>
/// Упаковка сообщения от клиента
/// </summary>
/// <param name="loadToken"></param>
/// <returns></returns>
public byte[] MessageToArray(bool loadToken = false)
{
byte[] message;
var result = new byte[Length + LengthAndDataType];
var result = loadToken ? new byte[Length + TokenLength + LengthAndDataType] : new byte[Length + LengthAndDataType];
result[0] = (byte)Type;
result[1] = (byte)Language;
//BinaryPrimitives.WriteInt32LittleEndian(result.AsSpan()[1..5], Length);
result[2] = loadToken ? (byte)1 : (byte)0; // 1 - токен есть | 0 - без токена(размер токена 10 байт)
if(Length > 0)
BinaryPrimitives.WriteInt32LittleEndian(result.AsSpan()[3..5], Length);

switch (Type)
{
case MessageType.Session:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.Token:
case MessageType.Registration:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.Log:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.File:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.Photo:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.Data:
message = Encoding.UTF8.GetBytes("1");
break;
default:
return result;
break;
}

if (loadToken)
{
Array.Copy(Encoding.UTF8.GetBytes("1234567890"), 0, result, LengthAndDataType, TokenLength);
Array.Copy(message ?? [0], 0, result, LengthAndDataType + TokenLength, Length);
}
else
Array.Copy(message ?? [0], 0, result, 6, Length);

return result;
}

/// <summary>
/// Упаковка сообщения от сервера
/// </summary>
/// <param name="loadToken"></param>
/// <returns></returns>
internal byte[] MessageServerToArray(bool loadToken = false)
{
byte[] message;
int lengthByte = loadToken ? Length + TokenLength + LengthAndDataType : Length + LengthAndDataType;

var result = new byte[lengthByte];
result[0] = (byte)Type;
result[1] = (byte)Language;
result[2] = loadToken ? (byte)1 : (byte)0; // 1 - токен есть | 0 - без токена(размер токена 10 байт)
if (Length > 0)
BinaryPrimitives.WriteInt32LittleEndian(result.AsSpan().Slice(3,5), lengthByte);

switch (Type)
{
case MessageType.Session:
message = Encoding.UTF8.GetBytes("1");
break;
case MessageType.Token:
message = Encoding.UTF8.GetBytes("1234567890");
break;
case MessageType.Registration:
message = Encoding.UTF8.GetBytes("1");
break;
Expand All @@ -87,17 +174,55 @@ public byte[] MessageToArray()
message = Encoding.UTF8.GetBytes("1");
break;
}
Array.Copy(message ?? [0], 0, result, 6, Length);

if (loadToken)
Array.Copy(message ?? [0], 0, result, LengthAndDataType, Length);
else
Array.Copy(message ?? [0], 0, result, LengthAndDataType, Length);

return result;
}

/// <summary>
/// Распаковка сообщения
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static MessageHeader FromArray(ReadOnlySpan<byte> buffer)
{
if (buffer.Length <= LengthAndDataType)
return new MessageHeader((MessageType)buffer[0], 0);
else
return new MessageHeader(Encoding.UTF8.GetString(buffer.ToArray(), LengthAndDataType, buffer.Length - LengthAndDataType), (MessageType)buffer[0], BinaryPrimitives.ReadInt32LittleEndian(buffer[1..]));

switch ((MessageType)buffer[0])
{
case MessageHeader.MessageType.Check:
return new MessageHeader((MessageType)buffer[0], (Languages)buffer[1], 0);
break;
case MessageHeader.MessageType.Session:
return null;
break;
case MessageHeader.MessageType.Token:
//return new MessageHeader(Encoding.UTF8.GetString(buffer.ToArray(), LengthAndDataType, buffer.Length - LengthAndDataType), (MessageType)buffer[0], BinaryPrimitives.ReadInt32LittleEndian(buffer[1..])); // сохраняем, добавляем данные. Данные передаются в кодированном формате, будем использовать кодировку UTF8, раскодируем байты
return new MessageHeader((MessageType)buffer[0], (Languages)buffer[1], Encoding.UTF8.GetString(buffer.ToArray(), LengthAndDataType, buffer.Length - LengthAndDataType), buffer[3] + buffer[4] + buffer[5]);
break;
case MessageHeader.MessageType.Registration:
case MessageHeader.MessageType.Log:
case MessageHeader.MessageType.File:
case MessageHeader.MessageType.Photo:
case MessageHeader.MessageType.Data:
case MessageHeader.MessageType.Title:
case MessageHeader.MessageType.TitleLoading:
default:
return null;
break;
}



//if (buffer.Length <= LengthAndDataType)
// return new MessageHeader((MessageType)buffer[0], (Languages)buffer[1], 0);
//else if (buffer[2] == 1)
// return new MessageHeader(Encoding.UTF8.GetString(buffer.ToArray(), LengthAndDataType, buffer.Length - LengthAndDataType), (MessageType)buffer[0], BinaryPrimitives.ReadInt32LittleEndian(buffer[1..]));
//else
// return new MessageHeader(Encoding.UTF8.GetString(buffer.ToArray(), LengthAndDataType, buffer.Length - LengthAndDataType), (MessageType)buffer[0], BinaryPrimitives.ReadInt32LittleEndian(buffer[1..]));
}
}
}
47 changes: 16 additions & 31 deletions ServerTCP/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;

namespace ServerTCP
Expand All @@ -31,28 +32,35 @@ static void Main(string[] args)
try
{
Console.WriteLine("Ожидаем соединение через порт {0}", endPoint);
var listener = tcpSocket.Accept(); // новый сокет для нового клиента
var listener = tcpSocket.Accept(); // новый с окет для нового клиента
Console.WriteLine("Подключился!");
var buffer = new byte[256]; // размер буфера . максимум сообщение из 256 байт
var size = 0; // количество реально полученных количества байт, потом чтобы оптимизировать память
do
{
size = listener.Receive(buffer); // получение данных, количество, значение
//buffer = buffer.Where(x => x != 0).ToArray();
var header = MessageHeader.FromArray(buffer);
//byte[] cleanBuffer;
//var lenghtBuffer = buffer[3] + buffer[4] + buffer[5];
//if (buffer[2] == 1)
// lenghtBuffer += 10;
//cleanBuffer = buffer.Take(lenghtBuffer).ToArray();
var header = MessageHeader.FromArray(buffer.Take(size).ToArray());

MessageHeader headerRequest = null;
byte[] headerRequestBytes;
string message = string.Empty;
bool loadToken = false;
switch (header.Type)
{
case MessageHeader.MessageType.Check:
headerRequest = new MessageHeader("1", MessageHeader.MessageType.Check, 1);
headerRequestBytes = headerRequest.MessageToArray();
listener.Send(headerRequestBytes);
break;
case MessageHeader.MessageType.Session:
break;
case MessageHeader.MessageType.Token:
message = "1234567890";
loadToken = true;
headerRequest = new MessageHeader(message, MessageHeader.MessageType.Token, message.Length);
break;
case MessageHeader.MessageType.Registration:
var user = new User
Expand All @@ -73,18 +81,11 @@ static void Main(string[] args)
break;
case MessageHeader.MessageType.TitleLoading:
headerRequest = new MessageHeader("1", MessageHeader.MessageType.TitleLoading, 1);
headerRequestBytes = headerRequest.MessageToArray();
listener.Send(headerRequestBytes);
break;

//case MessageHeader<string>.MessageType.Title:
// string messageRequest = "Привет, пупс!";
// var header1 = new MessageHeader<string>(messageRequest, MessageHeader<string>.MessageType.Check, Encoding.UTF8.GetBytes(messageRequest).Length);
// byte[] headerBytes = header1.MessageToArray();
// listener.Send(headerBytes);
// break;
}
//data.Append(Encoding.UTF8.GetString(buffer, 0, size)); // сохраняем, добавляем данные. Данные передаются в кодированном формате, будем использовать кодировку UTF8, раскодируем байты

headerRequestBytes = headerRequest.MessageServerToArray(loadToken);
listener.Send(headerRequestBytes);
}
while (listener.Available > 0); // до тех пор, пока в нашем подключение есть данные, будет продолжаться считывание

Expand All @@ -99,21 +100,5 @@ static void Main(string[] args)
}
}
}

static void Send()
{
using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng())
{

alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
alice.HashAlgorithm = CngAlgorithm.Sha256;
var alicePublicKey = alice.PublicKey.ToByteArray();
CngKey bobKey = CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob);
byte[] aliceKey = alice.DeriveKeyMaterial(bobKey);
byte[] encryptedMessage = null;
byte[] iv = null;
Send(aliceKey, "Secret message", out encryptedMessage, out iv);
}
}
}
}

0 comments on commit c90c9f1

Please sign in to comment.