@OwDafuq

Как реализовать прием-передачу текста через сокет не закрывая и не открывая его каждый раз заново?

Доброе утро.

Есть примерно такой код:
public string Send(string Text, bool Read, Form uForm)
        {
            try
            {
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Connect("localhost", 10000);
                sock.Send(Encoding.UTF8.GetBytes(Text));

                if (Read)
                {
                    byte[] bytes = new byte[2048];
                    int bytesRec = sock.Receive(bytes);
                    sock.Dispose();
                    return Encoding.UTF8.GetString(bytes, 0, bytesRec);
                }
                else
                {
                    sock.Dispose();
                    return null;
                }
            }
            catch
            {
                AlertMessage.Show(uForm, "Серверная часть не доступна.");
                return null;
            }
        }


И как понятно ответ от сервера я могу читать только когда отправляю ему что либо, хочется поддерживать постоянное подключение к нему, а так же обрабатывать ответы.
Может кто, что-то подсказать как такое реализовать?
  • Вопрос задан
  • 523 просмотра
Пригласить эксперта
Ответы на вопрос 2
Vindicar
@Vindicar
RTFM!
Погоди, сначала разберемся в логике работы соединения. Есть как минимум два варианта работы:
А) Односторонний запрос-ответ, или ведущий-ведомый (то, что реализовано в приведенном коде). Т.е. клиент(ведущий) шлет запрос, получает ответ от ведомого, и либо закрывает соединение, либо шлёт еще запрос. Так работает HTTP, к примеру.
Б) произвольный порядок. И клиент, и сервер могут послать сообщение другой стороне в произвольный момент, но другая сторона не обязана отвечать немедленно. Так обычно работают IM-системы.

Для второго варианта работы логика будет примерно такой:
1. Установить соединение
2. Ждать, пока не появятся принятые данные, не поступят сообщения для отправки или не будет получен сигнал об остановке.
3. Если получен сигнал остановки, см. п. 11.
4. Проверить, есть ли принятые данные, если нет, см. п. 7.
5. Принять данные и разобрать их формат, преобразовав их в сообщения.
6. Обработать принятые сообщения, например сгенерировать событие.
7. Проверить, есть ли сообщения на отправку, если нет, см. п. 10.
8. Сформировать данные для отправки.
9. Отправить данные.
10. См. п. 2
11. Закрыть соединение.

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

Реализовать такую логику можно следующим образом: создаешь отдельный поток обработки соединения, который в цикле выполняет шаги 2-10. Этот поток должен предоставлять метод для постановки сообщения в очередь на отправку, и событие для реакции на принятые сообщения*.
В этом случае твоя основаная программа стартует этот поток, подписывается на его события, и дергает его метод отправки по мере надобности. Таким образом можно разделить код работы с сетью и GUI.

* Еще пригодится служебная мелочь, вроде команды на остановку потока и закрытие соединения, проверку наличия ошибок и тд. В простейшей программе без этого можно обойтись.
Ответ написан
Konstantin18ko
@Konstantin18ko
Стоматолог
Не знаю как на C#, но в Java есть разделение по потокам. Я так догадываюсь Read - это входящий поток, и его надо зациклить на while(true), а точнее whileRead != 0).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы