Tcpclient/server

Тема в разделе ".NET", создана пользователем WildDuck, 18 ноя 2007.

  1. WildDuck

    WildDuck Гость

    Добрый вечер! Возникла проблема с событием disconnect.. его просто нет в классах TcpClient/TcpServer.. кто-нибудь знает как лучше его организовать? в итоге нужно сделать так, чтобы при внезапном разрыве соединения, второе приложение сразу об этом узнало!
     
  2. Pasha

    Pasha Гость

    Для: WildDuck
    При внезапном разрыве соединения ты получишь IOException или SocketException при следующей попытке чтения/записи. А то, что события нет - недостатки самих сокетов. :D
     
  3. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    вообщето у TCP есть фенечка KEEP_ALIVE, вот только далеко не все реализации ее поддерживают =(
     
  4. Pasha

    Pasha Гость

    Начиная с win2k поддерживается, из .net можно включить через SetSocketOption. Вот только о разрыве соединения все равно узнаешь при попытке передачи данных :)
     
  5. WildDuck

    WildDuck Гость

    а как же тогда.. получается что нельзя полноценно использовать сокеты !? :)
    Хотябы KEEP_ALIVE ;) неособо удобно, но хотябы так. Спасибо!

    Нашол статейку вроде бы можно ... http://www.rsdn.ru/article/net/keep_alive.xml (Определение разрыва TCP-соединения) там все основано я так понимаю на том, что идет постоянное перепингивание.. :) а когда ответа нет, значит дисконект...
     
  6. Pasha

    Pasha Гость

    Для: WildDuck
    Хм. Что значит "полноценно использовать сокеты"? Сами сокеты так устроены, что узнать о разрыве соединения можно только при попытке передачи. :)
     
  7. WildDuck

    WildDuck Гость

    Вы имеете ввиду не реализация в .net , а вообще все сокеты так устроены?
     
  8. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    <!--QuoteBegin-Pasha+19:11:2007, 15:53 -->
    <span class="vbquote">(Pasha @ 19:11:2007, 15:53 )</span><!--QuoteEBegin-->Сами сокеты так устроены, что узнать о разрыве соединения можно только при попытке передачи.
    [snapback]86453" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    полагаю это справедливо только для блокирующих сокетов. в случае работы с сокетами в событийной модели по идее KEEP_ALIVE должен работать.
     
  9. Pasha

    Pasha Гость

    Для: Kmet
    Для н*цензура*кирующих сокетов то же самое. Подразумевается что клиент сначала явно попытается прочитать данные, а потом уже получит о разрыве соединения.
     
  10. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    <!--QuoteBegin-WildDuck+19:11:2007, 15:18 -->
    <span class="vbquote">(WildDuck @ 19:11:2007, 15:18 )</span><!--QuoteEBegin-->[snapback]86451" rel="nofollow" target="_blank[/snapback]</div>[/quote]
    если верить исходникам статьи, работает
     
  11. Pasha

    Pasha Гость

    Для: Kmet
    Там делается примерно следующее:
    Создается событие
    WSAEventSelect(sock, hEvents[1], FD_CONNECT|FD_READ|FD_CLOSE);
    Потом оно ожидается
    WaitForMultipleObjects (2, hEvents, FALSE, INFINITE);
    в случае, если события дождались, идет гадание по WSAEnumNetworkEvents, чего же именно дождались.
    Этот код заменяется на Socket.BeginReceive, и гадание по IAsyncResult. Проблема только в том, что event в этом коде - не событие в смысле .net. Событие в .net - это callback в C++. А сокеты не поддерживают callbacks.
     
  12. WildDuck

    WildDuck Гость

    В принцепи нашол банальный выход..свое событие -- while { чтение из сокета } если ошибка значит дисконект...

    По поводу событий у меня появился небольшой вопросик..
    Имею свое событие, допустим которое срабатывает после того
    как ко мне что-то пришло в сокет.. В общей части программы
    в пришедшем событии пишу допустим RichTextBox.text += TEXT;
    вылазиет исключение....пишет что нет доступа к RichTextBox,
    хотя подобный пример в другой программе работает, если быть
    точнее то он и в этой программе работает, и в этом событии)
    только вызванное другой функцией.. со стороны клиента,
    код один к одному фактически.
    Может быть при описании событий есть какая-нибудь хитрость?))

    заранее благодарен!
     
  13. WildDuck

    WildDuck Гость

    Код (Text):
    public partial class Form1 : Form
    {
    ConnectTCP сonnectTCP = new ConnectTCP();

    public Form1()
    {
    InitializeComponent();
    сonnectTCP.readData += new ConnectTCP.ReadDataTCP(сonnectTCP_readData);
    }

    ..... разные методы....

    void сonnectTCP_readData(string messageData)
    {
    richTextBox1.Text += messageData;
    }

    }


    public class ConnectTCP
    {
    public delegate void ReadDataTCP(string messageData);
    public event ReadDataTCP readData;

    protected void OnDataRead(string messageData)
    {
    try
    {
    ...... проверка пришедших данных

    readData(messageData);
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.ToString());  ... вот это то то исключение и срабатывает!
    // invalidOperationExcaption RichTextBox1.... access from a Thread ..
    }
    }

    клиент по приходу сообщения вызывает
    OnDataRead(сообщение)

    сервер по приходу сообщения вызывает
    OnDataRead(сообщение)

    }
    пока писал это сообщение разобрался... просто сервер был запущен через VS... спасибо!

    (выложил может кому поможет)
     
  14. Pasha

    Pasha Гость

    Для: WildDuck
    На самом деле проблема была в том, что richTextBox1.Text += messageData не из того потока, в котором он был создан. Уже не раз обсуждалось, поищи по форуму слово Invoke.
     
  15. WildDuck

    WildDuck Гость

    Спасибо! теперь понятно! (+1)
     
Загрузка...

Поделиться этой страницей