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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Socket client+server передается и принимается толь 
:(
    Опции темы
123456789igor
Дата 6.5.2014, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я хочу постоянно передавать от сервера клиенту массив байт, но получается передать только 1 раз. Никак не пойму почему.
Сервер:
Код

public ServerSocket(IPAddress ipAddress, int port)
        {
            _clients = new List<ClientModel>();

            _server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _server.Bind(new IPEndPoint(ipAddress, port));
            _server.Listen(20); 
            Accept();
        }

        private async void Accept()
        {
            
            for ( int i=0;i<10 ;i++)
            {
                var socket = await Task.Factory.FromAsync<Socket>(_server.BeginAccept, _server.EndAccept, true);
                var newClient = new ClientModel
                {
                    Id = _id++,
                    ClientSocket = socket
                };
                _clients.Add(newClient);
                await Send(1, "hello " + i + "");
            }
        }
public async Task Send(int id, String data)
        {
            var client = _clients.FirstOrDefault(cl => cl.Id == id);
            if(client == null) return;

            var byteData = Encoding.UTF8.GetBytes(data);
            await Task.Factory.FromAsync<int>(
              client.ClientSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, null, client.ClientSocket),
              client.ClientSocket.EndSend);
        }


Клиент:
Код

public ClientSocket()
        {
            _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        public bool Connect(IPAddress ipAddress, int port)
        {
            _client.Connect(ipAddress, port);
            if (!_client.Connected)
            {
                return false;
            }
            Receive();
            return true;
        }

private async void Receive()
        {
            var buffer = new byte[4096];
            for (; ; )
            {
                try
                {
                    var bytesRead = await Task.Factory.FromAsync<int>(
                            _client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, null, _client),
                             _client.EndReceive);
                    if (bytesRead <= 0) continue;

                    var message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    Console.WriteLine(message);
                }
                catch
                {
                    break;
                }
            }


Учитывать надо, что одновременных клиентов может быть несколько. Проблема в том, что на 2ой итерации Сервер ждет на "BeginAccept/EndAccept", а клиент на "BeginReceive/EndReceive". Т.е получается, что клиент готов получать, а сервер не знает об этом. Подскажите как решить проблему.
Интересный факт: Если запустить сервер, затем клиент, то передастся массив 1 раз. Но если(ничего не закрываяя) открыть новый экземпляр клиента и выполнить его, то первый экземпляр пример 2ой раз массив. Если 2ой экземпляр клиента выполнить ещё раз, то первый примет 3ий массив. И так далее
PM MAIL   Вверх
Экскалупатор
Дата 6.5.2014, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

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



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


З.Ы. а перестает слать, очевидно, из-за того, что закрывается соединение и сервер не инициирует новое(и это правильно).
PM MAIL ICQ   Вверх
123456789igor
Дата 6.5.2014, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Экскалупатор @ 6.5.2014,  11:22)
а почему не устраивает классический подход? когда сервер ничего ни о ком не знает и отвечает только на запросы клиента(как в идеале и должно быть). т.е. клиент делает запрос, сервер отдает ему пачку данных, клиент ее получает обрабатывает и сообщает серверу о том, что все принял и готов к следующей отправке или о том, что что то сломалось и предыдущая отправка не прошла и ее надо еще раз отправить. так будет ровнее все это выглядеть и работать. и лучше что бы сервер не хранил состояние, тогда будет меньше зависимостей и потенциальных точек отказа.


З.Ы. а перестает слать, очевидно, из-за того, что закрывается соединение и сервер не инициирует новое(и это правильно).

Можно по подробнее? Как это реализовать? Получается на стороне сервера и не нужен цикл? или я не так понял?
PM MAIL   Вверх
123456789igor
Дата 6.5.2014, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Думаю просто не хватает каких то колбэков что бы снова связать клиент и сервер. Но каких не могу понять
PM MAIL   Вверх
Экскалупатор
Дата 6.5.2014, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

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



Цитата(123456789igor @  6.5.2014,  13:34 Найти цитируемый пост)
Можно по подробнее? Как это реализовать? Получается на стороне сервера и не нужен цикл? или я не так понял? 


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

Цитата(123456789igor @  6.5.2014,  14:09 Найти цитируемый пост)
Думаю просто не хватает каких то колбэков что бы снова связать клиент и сервер. Но каких не могу понять 

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

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

Добавлено через 3 минуты и 31 секунду
SelfHost RestApi может будет интересно, вместо сокетов(хотя смотря для каких задач использовать)
PM MAIL ICQ   Вверх
123456789igor
Дата 7.5.2014, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



если у сервера убрать цикл, то все равно только 1 раз отправляет
PM MAIL   Вверх
Экскалупатор
Дата 7.5.2014, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

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



Цитата(123456789igor @  7.5.2014,  19:16 Найти цитируемый пост)
если у сервера убрать цикл, то все равно только 1 раз отправляет 

какой именно цикл имеется ввиду? сервер должен выполнять в цикле операцию обработки входящих запросов. т.е.
1. сервер стартует
2. привязывается к порту
3. ждет подключения
4. при подключении создает поток для обработки 
5. запускает его(сам в процессе не учавствует)
6. возвращаемся к пункту 3.


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

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


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

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


 




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


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

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