Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C# мини Чат

55K
17 марта 2010 года
borN_free
7 / / 17.03.2010
Доброе время суток.
Решил написать миниЧат, без навороченных функций. Хоть тема и заезженная, хоть и пересмотрел я кучу примеров - а хочет с нуля, да и свой. Приведу весь код, что бы было понятно в чем вопрос.

клиент .. WinForms
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace client
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
        InitializeComponent();
        }
       
        public int port = 1116; //умолчание
        public string adres = "192.168.100.21"; //умолчание

        private TcpClient tcpServer;
        private Thread thrMessaging;
        private StreamWriter swSender;
        private StreamReader srReceiver;
       
        public delegate void dgUpdateLabel(string msg);
       
        private void reg()
        {
            //создадим сокетное подключение для общения с сервером
            tcpServer = new TcpClient(adres, port);

            swSender = new StreamWriter(tcpServer.GetStream());
            srReceiver = new StreamReader(tcpServer.GetStream()); //принятие
           
            thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
            thrMessaging.Start();
            //ну и тут ваше что-то*/
            string resp = srReceiver.ReadLine();
            label1.Text = resp;
           
        }
       
        public void SendMessage(string message) {  // отправка сообщений
            swSender.WriteLine(message);
            swSender.Flush();
            textBox1.Text = "";
        }
       
        public void ReceiveMessages() { // принятие сообщений от сервера
            srReceiver = new StreamReader(tcpServer.GetStream()); //принятие
            string Response = srReceiver.ReadLine();
           
            while (true) {
                if (Response != "") {
                    this.Invoke(new dgUpdateLabel(this.UpdateLog), new object[] { srReceiver.ReadLine() }); // обновляем текстбокс
                    Thread.Sleep(1000);
                }
            }          
        }
       
        public void UpdateLog(string msg) {
            textBox2.AppendText(msg+"\r\n");
        }
       
        void Button1Click(object sender, EventArgs e)
        {
            this.reg();
        }
       
        void Button2Click(object sender, EventArgs e)
        {
            this.SendMessage(textBox1.Text);
        }
       
        void MainFormFormClosed(object sender, FormClosedEventArgs e)
        {
            //swSender.Close();
            //srReceiver.Close();
            //tcpServer.Close();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //ReceiveMessages();
        }
       
        void TextBox1KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13) {
                this.SendMessage(textBox1.Text);
            }
        }
       
        void TextBox1TextChanged(object sender, EventArgs e)
        {
            // ...
        }
    }
}


и сервер.. (консольное приложение)

Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;

namespace server
{
    class Program
    {
        //для оздания отдельного процесса
        public class Connection
        {
            public TcpClient cl;
            StreamWriter swSender;
            StreamReader srReceiver;
            String str;
           
            public void Work()
            {
                srReceiver = new StreamReader(cl.GetStream()); //принятие
                swSender = new StreamWriter(cl.GetStream());
               
                // сообщаем об успешном подключении
                swSender.WriteLine("Connection Successfuly!");
                swSender.Flush();
                str = srReceiver.ReadLine();
               
                while(true) { // цикл для принятия сообщений от клиента
                    Thread.Sleep(50);
                    Console.WriteLine(str); // выводим в консоль принятое сообщение
                    str = srReceiver.ReadLine();
                    //SendMsgToClient(str);
                }
            }
           
            public void SendMsgToClient(string msg) {
                swSender = new StreamWriter(cl.GetStream());
                swSender.WriteLine(msg);
            }
           
            public void Sender() {
                swSender = new StreamWriter(cl.GetStream());
                //srReceiver = new StreamReader(cl.GetStream());
                //string response;
                //(response = srReceiver.ReadLine())
                while (str != "") {
                    Thread.Sleep(50);
                    if (str != null) {
                        swSender.WriteLine(str);
                        swSender.Flush();
                    }
                }
            }
        }
        //многопроцессорная работа
        static void Main(string[] args)
        {
            Console.WriteLine("Maka's (c) Server, the version 1.0.0.0 [borN_free]");

            int port = 1116;
            IPAddress localAdd = IPAddress.Parse("192.168.100.21");
            TcpListener server = new TcpListener(localAdd, port);

            server.Start(); //серер запущен
            Console.WriteLine("The server is started... Waiting for connections..."); //уведомили об этом

            while (true)
            {
                TcpClient cl = server.AcceptTcpClient();
                Console.WriteLine("Connected!");
                Connection c = new Connection();
                c.cl = cl;
                Thread t = new Thread(new ThreadStart(c.Work));
                t.IsBackground = false;
                t.Start();
               
                // поток для отправки сообщений ОТ сервера
                Thread sendThread = new Thread(new ThreadStart(c.Sender));
                sendThread.IsBackground = false;
                sendThread.Start();
            }
        }
    }
}


Ребята, главный мой вопрос и непонимание находится в сервере.. Я из клиента отправляю сообщение серверу, сервер должен принять его, и (в дальнейшем) разослать всем клиентам. в данном случае - отослать принятое сообщение обратно клиенту. Так вот и не понимаю я, правильно ли я использую потоки, в какой из функций я должен принимать/отправлять от сервера обратно сообщение, в Work или в Sender??
прошу дать совет, очень хочется разобраться.
Спасибо.
34K
18 марта 2010 года
shadowmaster63
93 / / 16.12.2009
Не всматривался в код но как я думаю если он сам рассылает всем пользователям сообщения.. то это большая нагрузка чем если бы клиенты сами забирали с сервера сообщения.
55K
18 марта 2010 года
borN_free
7 / / 17.03.2010
да не будет там большой нагрузки.. клиентов пару штук )

изменил код в сервере на такой

Код:
public void Work()
            {
                srReceiver = new StreamReader(cl.GetStream()); //принятие
                swSender = new StreamWriter(cl.GetStream());
                               
                // сообщаем об успешном подключении
                swSender.WriteLine("Connection Successfuly!");
                swSender.Flush();
                str = "";
               
                //str = srReceiver.ReadLine();
                //clientQueue.Enqueue(str);
                while((str = srReceiver.ReadLine()) != "") { // цикл для принятия сообщений от клиента
                        clientQueue.Enqueue(str);
                        Thread.Sleep(50);
                        Console.WriteLine(str); // выводим в консоль принятое сообщение
                }
            }
           
            public void Sender() {
                TcpClient[] tcpClients = new TcpClient[htUsers.Count]; // содержит массив клиентов
                string[] namesClients = new string[htUsers.Count]; // массив ников клиентов
               
                htUsers.Values.CopyTo(tcpClients, 0);
                htUsers.Keys.CopyTo(namesClients, 0);
                int k = 0, p=0;

                string msg;
                while (true) {
                    Thread.Sleep(5000);
                    while (clientQueue.Count > 0) {
                        msg = (string)clientQueue.Dequeue();
                        k = 0;
                        for (k= 0; k< tcpClients.Length; k++) {
                            StreamWriter swSender = new StreamWriter(tcpClients[k].GetStream());
                            swSender.WriteLine(msg);
                            swSender.Flush();
                        }  
                    }
                }
            }
           
        }


теперь из одного клиента НЕ ВСЕГДА, а точнее редко доходят сообщения до другого, и наоборот. В чем может быть проблема? ведь в цикле отправляются сообщения каждому. Может ли быть здесь конфликт потоков с разделяемым ресурсов очередью?
Спасибо
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог