C # Получение пакета в System.Sockets с примерами - PullRequest
1 голос
/ 18 апреля 2019

в этом вопросе C # Получение пакета в System.Sockets парень спросил: "В моем клиент-серверном приложении я задавался вопросом, как сделать пакет и отправить его на сервер через клиент Затем на сервере я узнаю, что это за пакет, и отправляю правильное воспроизведение "

и показал пример его способа реализации «распознавателя пакетов». Он получил ответ, что его способ «структурирования сообщения» плох, но нет объяснения и примера кода, за которым следует ответ.

Так что, пожалуйста, кто-нибудь может показать пример хорошего кода, который должен сделать что-то вроде этого, но правильным способом:

[клиент]

Send(Encoding.ASCII.GetBytes("1001:UN=user123&PW=123456")) //1001 is the ID

[сервер]

private void OnReceivePacket(byte[] arg1, Wrapper Client)
{
    try
    {
        int ID;
        string V = Encoding.ASCII.GetString(arg1).Split(':')[0];
        int.TryParse(V, out ID);

        switch (ID)
        {
            case 1001://Login Packet
                AppendToRichEditControl("LOGIN PACKET RECEIVED");
                break;

            case 1002:
                //OTHER IDs
                break;

            default:
                break;
        }
    }
    catch { }         
}

1 Ответ

0 голосов
/ 18 апреля 2019

TCP гарантирует, что данные поступают в том же порядке, в котором они были отправлены, но не имеют понятия сообщений . Например, допустим, вы отправили следующие два фрагмента данных:

1001:UN=user123&PW=123456
999:UN=user456&PW=1234

На принимающей стороне вы прочитаете 1001:UN=user123&PW=123456999:UN=user456&PW=1234, и это может занять одно, два или более чтений. Это может даже прибыть в двух пакетах как:

1001:UN=user123&PW=12
3456999:UN=user456&PW=1234

Это заставляет очень правильно анализировать сообщение. В другом сообщении упоминается об отправке длины пакета до фактических данных, и это действительно решает проблему, поскольку вы можете точно определить, когда заканчивается одно сообщение, а начинается следующее.

В качестве примера клиент и сервер могут договориться, что каждое сообщение начинается с 4 байтов, содержащих длину сообщения. Получатель мог тогда просто:

  • загрузить 4 байта точно
  • преобразовать в целое число, теперь вы знаете длину оставшейся части сообщения
  • прочитайте ровно столько байтов и проанализируйте сообщение

C # удобно имеет класс BitConverter, который позволяет преобразовать целое число в байт [] и наоборот.

...