Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нужна помощь с сокетами и самописным веб сервером! 
V
    Опции темы
MrKol999
Дата 26.4.2013, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.4.2013

Репутация: нет
Всего: нет



У меня возникла тут такая не хилая проблемка при написании сервера на C# для недоигрушки на javascript.
Принцип работы сервера:
Сидит, слушает. Обрабатывать должен и запросы из браузера, и запросы от самой игры. Пока что единственные запросы - сохранить/загрузить карту. Карта - JSON файл, который тупо сохраняется/загружается в/из папку/папки на сервере.
А из браузера запросы идут по типу "http://адрес:порт/ТИП_ЗАПРОСА?параметр1&параметр2&параметр3....". К примеру сама игра открывается вот так: "http://адрес:порт/GET_FILE?files/editor.html". Всё это дело писал я писал сам, никаких веб серверов от сторонних разработчиков не использую, и использовать не хочу, ибо он ещё и за саму игру будет отвечать(нет, не просчитывать физику, просто обеспечивать связь между всеми клиентами).

Суть проблемы:
Сокет получает байты N миллисекунд в отдельном треде, и N зависит от длинны входных данных. Длинна входных данных может быть простой адрес введённый в браузерную строку, а может быть и >9000 байт посланных клиентом для сохранения карты. Заполняет сокет массив через ссылку, и по этому сокет начинает принимать данные, и на момент, когда начался парсинг входных данных успел принять всего скажем, 2000 байт из 9000. При запросах из браузера всё нормально, а вот при сохранении карт - обрезание JSON файла, ну и всё ломается.

Код:
Код


while(true)
{
    Socket mySocket = myListener.AcceptSocket();

    if(mySocket.Connected)
    {
        Console.WriteLine("\n<<<<<<<==================\nClient connected!!\nClient IP {0}\n", mySocket.RemoteEndPoint);
        Console.WriteLine ("Socket Type: " + mySocket.SocketType );

        byte[] bReceive = new byte[mySocket.ReceiveBufferSize]; //только так, листы 
        mySocket.Receive(bReceive, bReceive.Length, 0); //Получение байтов.

        //Здесь нужно ждать, пока сокет примет ВСЕ байты. Как? Самому интересно!
        
        bReceive = (from b in bReceive where b != 0 select b).ToArray(); //Убираем нуллы, они дальше ненужны, и только всё портят.

        string sBuffer = HttpUtility.UrlDecode(Encoding.ASCII.GetString(bReceive));
                    
        Console.WriteLine("Client sent me this: \n{0}\n", sBuffer);

        //Здесь идёт парсинг данных, он большой, я его вырезал.
    }
}


Можно конечно ставить ETX (ASCII символ End Of Text), или что-либо подобное, но при запросе из браузера это не сработает, ибо он после запроса дописывает всякую информацию различной длинны.

Я заметил вот что: если запрос маленький(из браузера на пример, или просто на загрузку файла с сервера из самой игры), то в конце записываются куча ASCII символов NULL, и это натолкнуло меня на мысль, что оно работает как стрим. Естественно приходит в голову тормозить основной тред, и ждать, пока не появятся нуллы. Но, я никак не могу подцепится к сокету, и заставить его вызывать мою функцию каждый раз, как он получает байт. Можно конечно просто итерировать по всем символам массива, пока не найдём NULL и каждый раз ждать 1 миллисекунду, но опять же, время итерирования накапливается, и превращается в 1-10 секунд, а то и в минуту. А это плохо, все байты могут уже прийти, а сервер всё ещё итерирует их, ища NULL.

Есть ещё вот это:

Код


int i = mySocket.Receive(bReceive, bReceive.Length, 0);

byte[] bar;

while(true)
{
    bar = (from b in bReceive where b != 0 select b).ToArray();
    if (bar.Length == i) break;
    Thread.Sleep(10);
}

bReceive = bar;


Но оно тоже не работает.

На этом у меня идеи закончились, гугл тоже не помогает.
Помогите, люди добрые, что делать?

П.С.

Я крайне не уверен в проблеме, возможно она в другом, и тем не менее, Socket.Receive заполняет массив не полностью. На клиенте всё проверял, отсылает то, что требуется.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1127 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.