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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VC#] Работа с сокетами используя формы, Работа с сокетами не в консоли. 
:(
    Опции темы
MuForum
Дата 14.10.2007, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



Доброе время суток всем жителям данного Форума!

Задача: Написать программу, которая при активирование кнопки будет прослушивать указанный порт.
Проблема: Из-за того, что работает цикл программа становится не активна.

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;

namespace ConnectServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            richTextBox1.AppendText("Program was start!" + Environment.NewLine);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int recv;
            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 60000);
            //IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            newsock.Bind(ipep);
            newsock.Listen((int)SocketOptionName.MaxConnections);
            richTextBox1.AppendText("Waiting for a client..." + Environment.NewLine);
            Socket client = newsock.Accept();
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
            richTextBox1.AppendText(string.Format("Connected with {0} at port {1}", clientep.Address, clientep.Port) + Environment.NewLine);
            while (true)
            {
                data = new byte[1024];
                recv = client.Receive(data);
                if (recv == 0) break;

                richTextBox1.AppendText(Encoding.ASCII.GetString(data, 0, recv) + Environment.NewLine);
                client.Send(data, recv, SocketFlags.None);
            }
            richTextBox1.AppendText(string.Format("Disconnected from {0}", clientep.Address) + Environment.NewLine);
            client.Close();
            newsock.Close();
        }
    }
}


Задача: Сделать так, Чтобы при нажатие на кнопку(button1) активировалось прослушивание данного порта.

Это сообщение отредактировал(а) MuForum - 14.10.2007, 01:57


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
tol05
Дата 14.10.2007, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

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



весь код работы с сокетом вынеси в отдельный поток. Поток запускай по кажатию кнопки. Обновление контролов данными, полученными сокетом, делай через метод Invoke().

Поищи на форуме. Только не в общих вопросах, а в "Распределенные приложения и сеть" или "Разработка Windows Forms".
 Примеров достаточно.


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
MuForum
Дата 19.10.2007, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



#2, tol05 - Попользовался поиском, искал в двух разделах: "Распределённые приложения и сеть" и "Разработка Windows Forms".
- К сажалению толком ничего толком полезного не нашел =(

Так же гуглил несколько дней, попутно нашел пару интересных статеек, думаю людям будет интересно почитать(По крайне мере советую всем новечкам в этом деле почитать):



P.S. -> Если у кого-то есть возможность и желание, то было бы не плохо какой-то приметивный пример работы с сокетами на C# опубликовать, так как честно говоря у меня так и не вышло сделать, чтобы форма не зависала(Потом сделал в потоке как говорилось, но затем выключить не мог нормально, тоже форма зависала, Но уже при выключении)...
- Вообщем хотелось бы помощи в этом деле более опытных людей.

Это сообщение отредактировал(а) MuForum - 19.10.2007, 23:56


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
tol05
Дата 20.10.2007, 12:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

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



Цитата(MuForum @  19.10.2007,  23:53 Найти цитируемый пост)
#2, tol05 - Попользовался поиском, искал в двух разделах: "Распределённые приложения и сеть" и "Разработка Windows Forms".
- К сажалению толком ничего толком полезного не нашел =(

ок, допустим не нашел.

Цитата(tol05 @  14.10.2007,  11:51 Найти цитируемый пост)
весь код работы с сокетом вынеси в отдельный поток

Цитата(tol05 @  14.10.2007,  11:51 Найти цитируемый пост)
Поток запускай по кажатию кнопки

Цитата(tol05 @  14.10.2007,  11:51 Найти цитируемый пост)
Обновление контролов данными, полученными сокетом, делай через метод Invoke().

где это все, где код? 

Цитата(MuForum @  19.10.2007,  23:53 Найти цитируемый пост)
- Вообщем хотелось бы помощи в этом деле более опытных людей.

ну а пока "более опытные люди" отдыхают, вот тебе то, о чем я говорил:
Код

public partial class Form1 : Form
    {
        public delegate void Append(String myString);
        private Thread thread;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            richTextBox1.AppendText("Program was start!" + Environment.NewLine);
        }

        private void SocketGoOn()
        {
            Append append = new Append(richTextBox1.AppendText);

            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 60000);
            //IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            richTextBox1.Invoke(append, new object[] { "The socket was created" + Environment.NewLine }); int recv;

            newsock.Bind(ipep);
            newsock.Listen((int)SocketOptionName.MaxConnections);

            richTextBox1.Invoke(append, new object[] {"Waiting for a client..." + Environment.NewLine});
        
            Socket client = newsock.Accept();
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

            richTextBox1.Invoke(append, new object[] { string.Format("Connected with {0} at port {1}", clientep.Address, clientep.Port) + Environment.NewLine });
            
            while(true)
            {
                data = new byte[1024];
                recv = client.Receive(data);
                if(recv == 0) break;
                richTextBox1.Invoke(append, new object[] { Encoding.ASCII.GetString(data, 0, recv) + Environment.NewLine });
                client.Send(data, recv, SocketFlags.None);
            }
richTextBox1.Invoke(append, new object[] { string.Format("Disconnected from {0}", clientep.Address) + Environment.NewLine });
            client.Close();
            newsock.Close();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            thread = new Thread(SocketGoOn);
            thread.IsBackground = true;
            thread.Start();
        }
    }



--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
MuForum
  Дата 21.10.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



#, tol05 - Ещё вопрос возник, вот как в потоке добавлять текст ты показал, я пытался тоже самое сделать для фокуса и Select, но у меня не вышло =(

Код

    public delegate void Append1(String myString);
    public delegate void Append2(int start, int length);
...
    private void WLog(String T)
    {
        Append1 append = new Append1(this.form.richTextBox1.AppendText);
        Append2 select = new Append2(this.form.richTextBox1.Select);
        this.form.richTextBox1.Focus();
        this.form.richTextBox1.Invoke(append, new object[] { "[" + DateTime.Now.ToLongTimeString() + "] " + T + Environment.NewLine });
        this.form.richTextBox1.Invoke(select, new object[] { this.form.richTextBox1.Text.Length, 0 }); // Вот тут проблема =(
    }



P.S. -> Но при попытке добавить новый текст в richTextBox1, компилятор подвисает, и дебагер ругается...

Это сообщение отредактировал(а) MuForum - 21.10.2007, 15:56


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 21.10.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



# for all - Проблему решил, спасибо корейским парням.

Код

    private void WLog(String T)
    {
        this.form.richTextBox1.Invoke((MethodInvoker)delegate { this.form.richTextBox1.Focus(); });
        this.form.richTextBox1.Invoke((MethodInvoker)delegate { this.form.richTextBox1.AppendText(string.Format("[{0}]  {1}",DateTime.Now.ToLongTimeString(), T) + Environment.NewLine); });
        this.form.richTextBox1.Invoke((MethodInvoker)delegate { this.form.richTextBox1.Select(this.form.richTextBox1.Text.Length, 0); }); // Moving the Caret in end of the text.
    }


Это сообщение отредактировал(а) MuForum - 21.10.2007, 16:33


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
tol05
Дата 21.10.2007, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

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



MuForum, передай 
Цитата(MuForum @  21.10.2007,  16:15 Найти цитируемый пост)
корейским парням
 что можно и так писать:
Код

 private void WLog(String T)
    {
        this.form.richTextBox1.Invoke((MethodInvoker)delegate { 
              this.form.richTextBox1.Focus();
              this.form.richTextBox1.AppendText(string.Format("[{0}]  {1}",DateTime.Now.ToLongTimeString(), T) + Environment.NewLine); 
              this.form.richTextBox1.Select(this.form.richTextBox1.Text.Length, 0); });
    }
 smile 

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

Ты бы попробовал через события поработать. Вынеси код потока в отдельный класс, объяви в нем события, привяжи к ним обработчики формы. Когда в потоке что-то происходит - возбуждай событие, а форма это событие обработает сама. 

Т.о. у тебя будет независимый код логики потока, который время от времени сообщает (всем, кто подпишется) о своем состоянии.


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
MuForum
Дата 21.10.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



Цитата(tol05 @ 21.10.2007,  18:23)
MuForum, передай 
Цитата(MuForum @  21.10.2007,  16:15 Найти цитируемый пост)
корейским парням
 что можно и так писать:
Код

 private void WLog(String T)
    {
        this.form.richTextBox1.Invoke((MethodInvoker)delegate { 
              this.form.richTextBox1.Focus();
              this.form.richTextBox1.AppendText(string.Format("[{0}]  {1}",DateTime.Now.ToLongTimeString(), T) + Environment.NewLine); 
              this.form.richTextBox1.Select(this.form.richTextBox1.Text.Length, 0); });
    }
 smile 

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

Ты бы попробовал через события поработать. Вынеси код потока в отдельный класс, объяви в нем события, привяжи к ним обработчики формы. Когда в потоке что-то происходит - возбуждай событие, а форма это событие обработает сама. 

Т.о. у тебя будет независимый код логики потока, который время от времени сообщает (всем, кто подпишется) о своем состоянии.

Цитата

MuForum, передай 
Цитата(MuForum @  21.10.2007,  16:15 Найти цитируемый пост)
корейским парням
 что можно и так писать:


- Это нашел на одном из корейских Форумах тему, там было в заголовке текст: "richTextBox1.Invoke", ну я и начал разбирать код, затем увидел этот вариант и уже переделал под себя =)

Цитата

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


- Да, я делаю "ConnectServer", программу, которая будет связывать игроков с главным Сервером. На C++ я это уже реализовывал детом этого года, но сейчас хочу это реализовать на C# =)

P.S. -> Если у тебя есть возможность и желание, ты не мог бы пожалуйста более развёрнуто объяснить, чтобы я хоть более немение понимал о чём речь и смог поискать в Интернете.

- Заранее благодарен.


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
tol05
Дата 21.10.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

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



Цитата(MuForum @  21.10.2007,  18:37 Найти цитируемый пост)
 Если у тебя есть возможность и желание, ты не мог бы пожалуйста более развёрнуто объяснить, чтобы я хоть более немение понимал о чём речь и смог поискать в Интернете.

Что именно объяснить? Я вроде объяснил уже smile

У тебя есть достаточно большой кусок кода, работающего в отдельном потоке.
Есть форма для ввода-вывода результатов.

Код потока выполняет много разнообразных действий, получается, что через каждые несколько строк нужно посылать форме ссобщения о чем-то. Вот и сделай в форме класс Worker, создавай его и инициализируй нужными ему данными. Давай ему команду работать. Он с твоими данными начнет работу, и, время от времени, будет возбужлать свои события "Я включился", "Я получил данные", "Я отправил данные" и т.п.
А в форме, после создания экземпляра Worker, подпишись на его события. Вот и все. Отключил одну форму, подключил другую - от этого Worker не изменится. И аналогично с другой стороны - отключил Worker - форма дальше работает, только событий не получает и обработчиков своих не вызывает.

вот и все, в принципе smile


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
shubert
Дата 20.11.2007, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.12.2006
Где: Mосква

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



Посмотрел ветку через события делается легче. если хочешь могу выложить свой клиент только работает с асинхронными вызовами, как только поступают данные вызываются события. 
PM MAIL ICQ   Вверх
MuForum
Дата 28.11.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



#10, shubert - Ну если есть возможность, то опубликую свою работу, что-то я для себя извлеку и может кому-то тоже понадобится.


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
shubert
Дата 30.11.2007, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.12.2006
Где: Mосква

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



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

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  AClientServer.cs 26,81 Kb
PM MAIL ICQ   Вверх
shubert
Дата 30.11.2007, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.12.2006
Где: Mосква

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



Код

    #region Делегаты
    public delegate void ADelegate(object sender, string st);
    public delegate void ReceiveDelegate(object sender, string st, int count);
    public delegate void ErrorDelegate(Exception error, string st);
    #endregion
    /// <summary>
    /// класс для работы TCP/IP клиентом. построен на асинхронных методах.
    /// </summary>
    public class AClient
    {
        #region Закрытые Поля
        private   int    port=0;
        private   string ip="127.0.0.1";
        internal  Socket s=null;        
        private   bool   connected=false;
        private   byte[] buffer=null;
        private   int    buffersize=1024;
        private   bool   blocking=false;
        private   bool   reconnect=false;
        private   int    countreconnect=0;
        private   int    timereconnect=1;     //через сколько секунд будет произведен реконнект.
        private   int    i=0;                 //счетчик реконектов.
        private   bool   stopreconnect=false;
        #endregion

        #region Свойства
        /// <summary>
        /// Connected=true - связь установлена,
        /// Connected=false - связь не установлена.
        /// </summary>
        public bool    Connected
        {
            get
            { return connected;}
        }
        public int     BufferSize
        {
            get
            { return buffersize;}
            set
            { buffersize = value;}
        }
        public byte[]  Buffer
        {
            get
            {return buffer;}
        }
        public int     Port
        {
            get
            {return port;}
            set
            {port = value;}
        }
        public string  IP
        {
            get
            {return ip;}
            set
            {ip = value;}
        }
        public bool    Blocking
        {
            get
            {return blocking;}
            set
            {blocking = value;}
        }
        public bool    Reconnect
        {
            get
            {return reconnect;}
            set
            {reconnect = value;}
        }
        public int     CountReconnect
        {
            get
            {return countreconnect;}
            set
            {countreconnect = value;}
        }
        public int     TimeReconnect
        {
            get
            {return timereconnect;}
            set
            {timereconnect = value;}
        }
        #endregion

        #region Констуктор
        /// <summary>
        /// Конструктор асинхронного клиента
        /// </summary>
        public AClient()
        {
            try
            {
                s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                this.OnDisconnect += new ADelegate(AClient_OnDisconnect);
            }
            catch (SocketException error)
            {
                if (OnError != null)
                    OnError(error, "Ошибка создания сокета.");
            }
        }

       
        /// <summary>
        /// Конструктор асинхронного клиента
        /// </summary>
        /// <param name="ip_">IP адрес удаленного хоста</param>
        /// <param name="port_">Порт удаленного хоста</param>
        public AClient(string ip_, int port_)
        {
          ip = ip_;
          port = port_;
          try
          {
              s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
              this.OnDisconnect += new ADelegate(AClient_OnDisconnect);
          }
          catch (SocketException error)
          {
              if (OnError != null)
                  OnError(error, "Ошибка создания сокета.");
          }
          
        }
        #endregion

        #region События
        /// <summary>
        /// Связь с удаленным хостом установлена.
        /// </summary>
        public event ADelegate        OnConnected;
        /// <summary>
        /// Связь с удаленным хостом разорвана.
        /// </summary>
        public event ADelegate        OnClose;
        /// <summary>
        /// Данные удаленному хосту отправлены.
        /// </summary>
        public event ADelegate        OnSend;
        /// <summary>
        /// Произошел разрыв соединения. Повторить установления связи с удаленным хостом.
        /// </summary>
        public event ADelegate        OnReconnected;
        /// <summary>
        /// Данные поступили от удаленного хоста.
        /// </summary>
        public event ReceiveDelegate  OnReceive;
        /// <summary>
        /// Произошла ошибка.
        /// </summary>
        public event ErrorDelegate    OnError;
        /// <summary>
        /// Происходит закрытие сокета. Прекращение сеанса.
        /// </summary>
        public event ADelegate        OnClosing;

        public event ADelegate        OnDisconnect;

        void AClient_OnDisconnect(object sender, string st)
        {
            if (!stopreconnect)
            {
                Reconnecting();
            }
        }
        #endregion

        #region Методы

        public void Connect()
        {
            if (connected == false)
            {
                try
                {
                    if (s == null)
                        s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                    s.Blocking = blocking;                    
                    s.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port), new AsyncCallback(ConnectCallBack), s);
                }
                catch (SocketException error)
                {
                    if (OnError != null)
                        OnError(error, "Ошибка установления соединения с удаленным хостом.");
                }
            }
            else
            {
                if (OnError != null)
                    OnError(new SocketException((int)SocketError.IsConnected), "Связь с удаленным хостом уже установлена.");
            }
        }

        public void Connect(string IP_, int Port_)
        {
            ip = IP_;
            port = Port_;
            Connect();
        }

        public void Connect(ProxyType Type, string ProxyIP, int ProxyPort, string IP_, int Port_)
        {

        }

        public void Disconnect()
        {
            if (OnClosing != null)
                OnClosing(this, "Происходит закрытие сокета.");
            if (connected == true)
            {
                try
                {
                   connected = false;
                   stopreconnect = true;
                   s.Shutdown(SocketShutdown.Both);                   
                   s.Close();
                   s = null;                   
                   if (OnClose != null)
                       OnClose((object)this, "Сокет закрыт.");
                   OnDisconnect(this, "Дисконект");
                }
                catch (SocketException error)
                {
                    if (OnError != null)
                        OnError(error, "Ошибка закрытия сокета.");
                }
            }
            else
            {
                //connected = false;
                stopreconnect = true;
                s = null;
                if (OnError != null)
                    OnError(new SocketException((int)SocketError.NotConnected), "Сокет не соединен с сервером.");
                OnDisconnect(this, "Дисконект");
            }
        }
   
        public void Send(string st)
        {
            if (connected == true)
            {
                try
                {
                    byte[] temp_buffer = Encoding.ASCII.GetBytes(st);
                    s.BeginSend(temp_buffer, 0, temp_buffer.Length, 0, new AsyncCallback(SendCallBack), s);
                }
                catch (SocketException error)
                {
                    if (OnError != null)
                        OnError(error, "Ошибка при отправлении данных соединненому сокету.");
                    //if ((error.SocketErrorCode == SocketError.ConnectionAborted) ||
                    //    (error.SocketErrorCode == SocketError.Disconnecting))
                    //    connected = false;
                }
            }
            else
            {
                if (OnError != null)
                    OnError(new SocketException((int)SocketError.NotConnected), "Сокет не соединен с сервером.");
            }
        }
        
        private void Reconnecting()
        {
            //if (stopreconnect == false)
            {
                if (countreconnect == 0)
                {
                    OnReconnected(this, "Попытка установления нового соединения с удаленным хостом.");
                    Thread.Sleep(timereconnect*1000);
                    Connect();
                }
                else
                {
                    if (i < countreconnect)
                    {
                        i++;
                        OnReconnected(this, "Попытка установления нового соединения с удаленным хостом.");
                        Thread.Sleep(timereconnect*1000);
                        Connect();
                    }
                }
            }
        }

        private void Receive(Socket s)
        {
            if (connected == true)
            {
                try
                {
                    buffer = new byte[buffersize];
                    s.BeginReceive(buffer, 0, buffersize, 0, new AsyncCallback(ReceiveCallBack), s);
                }
                catch (SocketException error)
                {
                    connected = false;
                    if (OnError != null)
                        OnError(error, "Ошибка получения данных от соединенного сокета.");
                    if (reconnect == true)
                    {
                        stopreconnect = false;
                        OnDisconnect(this, "Дисконект");
                    }
                }
            }
        }

        #endregion

        #region Асинхронные Методы

        private void ConnectCallBack(IAsyncResult ar)
        {
                try
                {
                    Socket temp_socket = (Socket)ar.AsyncState;
                    temp_socket.EndConnect(ar);
                    connected = true;
                    if (OnConnected != null)
                        OnConnected(this, "Соединение установлено удачно.");
                    Receive(temp_socket);
                }
                catch (SocketException error)
                {
                    connected = false;
                    if (OnError != null)
                        OnError(error, "Ошибка установления соединения с удаленным хостом. Ошибка вызова ConnectCallback.");
                    if (reconnect == true)
                    {
                        stopreconnect = false;
                        OnDisconnect(this, "Дисконект");
                    }
                    
                    //if (reconnect == true)
                    //    Reconnecting();
                }
        }

        private void SendCallBack(IAsyncResult ar)
        {
            try
            {
                Socket temp_socket = (Socket)ar.AsyncState;
                int count = temp_socket.EndSend(ar);
                if (OnSend != null)
                    OnSend((object)this, "Отправлено " + count.ToString() + " байт.");
            }
            catch (SocketException error)
            {
                if (OnError != null)
                    OnError(error, "Ошибка при отправлении данных соединненому сокету. Ошибка вызова SendCallBack.");
            }

        }

        private void ReceiveCallBack(IAsyncResult ar)
        {
                try
                {
                    Socket temp_socket = (Socket)ar.AsyncState;
                    if ((temp_socket != null) && (temp_socket.Connected == true))
                    {
                        int count = temp_socket.EndReceive(ar);
                        if (count > 0)
                        {
                            if (OnReceive != null)
                                OnReceive((object)this, ASCIIEncoding.ASCII.GetString(buffer, 0, count), count);
                            Receive(temp_socket);
                        }
                        else
                        {
                            //throw new SocketException((int)SocketError.ConnectionAborted);
                            if (OnError != null)
                                OnError(new SocketException((int)SocketError.ConnectionAborted), "Прием пустых данных. Ошибка вызова ReceiveCallBack");
                            connected = false;
                            s.Shutdown(SocketShutdown.Both);
                            s.Close();
                            s = null;
                            if (reconnect == true)
                            {
                                stopreconnect = false;
                                OnDisconnect(this, "Дисконект");
                            }
                        }
                    }
                }
                catch (SocketException error)
                {
                    if (OnError != null)
                        OnError(error, "Ошибка получения данных от соединенного сокета. Ошибка вызова ReceiveCallBack");
                    connected = false;
                    s.Shutdown(SocketShutdown.Both);
                    s.Close();
                    s = null;
                    if (reconnect == true)
                    {
                        stopreconnect = false;
                        OnDisconnect(this, "Дисконект");
                    }
                }               
            
        }
        
        #endregion

    }

    #endregion


вот выкладываю код

Добавлено через 3 минуты и 54 секунды
Если найдете глюки сообщите.

Присоединённый файл ( Кол-во скачиваний: 21 )
Присоединённый файл  AClientServer.cs 26,81 Kb
PM MAIL ICQ   Вверх
Yama
Дата 12.12.2007, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



MuForum, используй асинхронные сокеты smile
И не надо будет тебе самому писать оберки на то, что в .нет уже давным давно завернуто за нас smile
--------------------
Если бы строители строили дома так же, как программисты пишут программы, то первый же залетевший в форточку дятел разрушил бы всю нашу цивилизацию.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

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

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Распределённые приложения и сеть | Следующая тема »


 




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


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

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