Async Sockets, получить несколько файлов по одному соединению - PullRequest
1 голос
/ 12 марта 2012

У меня есть сервер, который собирается передать несколько файлов клиенту через одно соединение. Пакет с сервера имеет следующий формат: unique_packet_id | file_content

У меня есть функция onDataReceived, которая мне нужна для работы следующим образом:

    public class TRACK_ID {
         public string id;
         public string unknown_identifier;
    }

    List<TRACK_ID> TRACKER = new List<TRACK_ID>();

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            log("OnDataReceived");
            SocketPacket theSockId = (SocketPacket)asyn.AsyncState;

            int iRx = theSockId.thisSocket.EndReceive(asyn); 

            // .. read the data into data_chunk

                // if seperator found, that means we got an first chunk with the id
                if (data_chunk.Contains("|") == true)
                {
                    // extract unique_packet_id from the data
                    // bind unique_packet_id to an some kind of identifier? how!!??
                    TRACK_ID new_track = new TRACK_ID();
                    new_track.id = unique_packet_id;
                    new_track.unknown_identifier = X;

                    TRACKER.add(new_track);

                } else {
                   // no seperator found - we're getting the rest of the data
                   // determinate the unique_packet_id of the incoming data so we can distinguish data/files           
                   string current_packet_id = "";

                   for(int i=0; i<TRACKER.count; i++){
                       if(TRACKER[i].unknown_identifier == X){
                               current_packet_id = TRACKER[i].id; // we found our packet id!
                               break;
                       }
                   }

                   // now we got our packet_id and know where to store the buffer

                }


             WaitForData..
        }

     }

Мне нужна переменная X, которая позволит мне отслеживать, где хранить каждый входящий буфер

Если бы я закрыл соединение для каждого файла, я мог бы связать unique_packet_id с socket_id (socket_id был бы X), но так как я использую то же соединение, socket_id всегда остается тем же, поэтому я должен использовать что-то еще для этой переменной X ,

Единственное другое решение, о котором я могу подумать, - это отправлять unique_packet_id в каждом фрагменте данных. Но это кажется не лучшим способом сделать это. Затем мне пришлось бы разбить файловый буфер на порции и добавить идентификатор для каждого порции. Есть ли другие способы, как это сделать? Спасибо!

1 Ответ

1 голос
/ 12 марта 2012

Вы не сказали, используете ли вы потоковый сокет или сокет дейтаграммы.

Если вы используете сокет дейтаграммы (например, вы используете UDP / IP), то вы всегда будете получать весь пакет сразу, поэтому вы сможете идентифицировать данные, потому что они соответствуют найденному unique_packet_id до | в начале текущего пакета.

Если вы используете потоковый сокет (например, вы используете TCP / IP), то, я думаю, у вас есть проблема. Ваш формат пакета не разделен или не экранирован, так как вы узнаете, где заканчивается один пакет и начинается следующий?

Если вы используете потоковый сокет, вам нужно, например, использовать формат пакета, подобный следующему:

  • уникальный идентификатор пакета (скажем, в ASCII, оканчивается на CRNL - или как вы выберете)
  • длина контента (в том же формате)
  • полезная нагрузка пакета

Получатель может найти конец пакета, потому что он знает, сколько байтов будет частью полезной нагрузки.

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

Другое возможное решение, о котором вы упоминаете, - отправка unique_packet_id в каждом фрагменте данных, невозможна, поскольку отправитель не знает, как данные будут разбиты на блоки при доставке получателю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...