Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
.NET 3.x

Чат TCP Консоль сервер + WinForm клиент

30.06.2016, 18:21. Показов 19710. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Чат TCP сервер консоль + WinForm клиент

Есть код где Консоль сервер+ Консоль клиент создает Чат

но когда это я перевел на Консоль сервер+ WinForm клиент
возникает проблема , при отправки через клиент сообщения
цикл стает бесконечен к зависанию , как и в WinForm клиент
что не хватает в коде этом ?

Консоль сервер Winform_Winform_Chat
файл Program.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Server_chat;
 
namespace Winform_Winform_Chat
{
    class Program
    {
        static ServerObject server; // сервер
        static Thread listenThread; // потока для прослушивания
        static void Main(string[] args)
        {
            Title_Console("Сервер Чат v 1.0");
            try
            {
                server = new ServerObject();
                listenThread = new Thread(new ThreadStart(server.Listen));
                listenThread.Start(); //старт потока
            }
            catch (Exception ex)
            {
                server.Disconnect();
                Console.WriteLine(ex.Message);
            }
        }
 
        static void Title_Console(string title)
        {
            Console.BackgroundColor = ConsoleColor.DarkCyan;
            Console.Clear();
            Console.ForegroundColor = ConsoleColor.White;
            Console.Title = title;
        }
 
        static void Pause()
        {
            Console.ReadKey(true);
        }
 
        static void Error_msg(string msg)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(msg);
            Console.ForegroundColor = ConsoleColor.White;
        }
    }
}
Обьект ServerObject.cs к Консоль серверу
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
namespace Server_chat
{
    class ServerObject
    {
        static TcpListener tcpListener; // сервер для прослушивания
        List<ClientObject> clients = new List<ClientObject>(); // все подключения
 
        protected internal void AddConnection(ClientObject clientObject)
        {
            clients.Add(clientObject);
        }
        protected internal void RemoveConnection(string id)
        {
            // получаем по id закрытое подключение
            ClientObject client = clients.FirstOrDefault(c => c.Id == id);
            // и удаляем его из списка подключений
            if (client != null)
                clients.Remove(client);
        }
        // прослушивание входящих подключений
        protected internal void Listen()
        {
            try
            {
                tcpListener = new TcpListener(IPAddress.Any, 8888);
                tcpListener.Start();
                Console.WriteLine("Сервер запущен. Ожидание подключений...");
 
                while (true)
                {
                    TcpClient tcpClient = tcpListener.AcceptTcpClient();
 
                    ClientObject clientObject = new ClientObject(tcpClient, this);
                    Thread clientThread = new Thread(new ThreadStart(clientObject.Process));
                    clientThread.Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Disconnect();
            }
        }
 
        // трансляция сообщения подключенным клиентам
        protected internal void BroadcastMessage(string message, string id)
        {
            byte[] data = Encoding.Unicode.GetBytes(message);
            for (int i = 0; i < clients.Count; i++)
            {
                if (clients[i].Id != id) // если id клиента не равно id отправляющего
                {
                    clients[i].Stream.Write(data, 0, data.Length); //передача данных
                }
            }
        }
        // отключение всех клиентов
        protected internal void Disconnect()
        {
            tcpListener.Stop(); //остановка сервера
 
            for (int i = 0; i < clients.Count; i++)
            {
                clients[i].Close(); //отключение клиента
            }
            Environment.Exit(0); //завершение процесса
        }
    }
}
Обьект ClientObject.cs к Консоль серверу
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
 
namespace Server_chat
{
    class ClientObject
    {
        protected internal string Id { get; private set; }
        protected internal NetworkStream Stream { get; private set; }
        string userName;
        TcpClient client;
        ServerObject server; // объект сервера
 
        public ClientObject(TcpClient tcpClient, ServerObject serverObject)
        {
            Id = Guid.NewGuid().ToString();
            client = tcpClient;
            server = serverObject;
            serverObject.AddConnection(this);
        }
 
        public void Process()
        {
            
                
           
            try
            {
                Stream = client.GetStream();
                // получаем имя пользователя
                string message = GetMessage();
                userName = message;
 
                message = userName + " вошел в чат";
                // посылаем сообщение о входе в чат всем подключенным пользователям
                server.BroadcastMessage(message, this.Id);
                Console.WriteLine(message);
                // в бесконечном цикле получаем сообщения от клиента
                while (true)
                {
                    try
                    {
                        message = GetMessage();
                        message = String.Format("{0}: {1}", userName, message);
                        Console.WriteLine(message);
                        break;
                        server.BroadcastMessage(message, this.Id);
                        Console.ReadKey(true);
                        //break;
                    }
                    catch
                    {
                        message = String.Format("{0}: покинул чат", userName);
                        Console.WriteLine(message);
                        server.BroadcastMessage(message, this.Id);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                // в случае выхода из цикла закрываем ресурсы
                server.RemoveConnection(this.Id);
                Close();
            }
            
        }
 
        // чтение входящего сообщения и преобразование в строку
        private string GetMessage()
        {
            byte[] data = new byte[64]; // буфер для получаемых данных
            StringBuilder builder = new StringBuilder();
            int bytes = 0;
            do
            {
                bytes = Stream.Read(data, 0, data.Length);
                builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
            }
            while (Stream.DataAvailable);
 
            return builder.ToString();
        }
 
        // закрытие подключения
        protected internal void Close()
        {
            if (Stream != null)
                Stream.Close();
            if (client != null)
                client.Close();
        }
    }
}
И так же
WinForm клиент Winform_Winform_Chat
файл Form1.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
 
namespace Client_Winform
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        static string userName;
        private const string host = "127.0.0.1";
        private const int port = 8888;
        static TcpClient client;
        static NetworkStream stream;
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            client = new TcpClient();
            try
            {
                client.Connect(host, port); //подключение клиента
                stream = client.GetStream(); // получаем поток
 
                string message = textBox1.Text;
                byte[] data = Encoding.Unicode.GetBytes(message);
                stream.Write(data, 0, data.Length);
                
                //// запускаем новый поток для получения данных
                Thread receiveThread = new Thread(new ThreadStart(ReceiveMessage));
                receiveThread.Start(); //старт потока
                //Console.WriteLine("Добро пожаловать, {0}", userName);
                SendMessage();
 
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Disconnect();
            }
        }
 
        // отправка сообщений
        private void SendMessage()
        {
 
 
            while (true)
            {
                //Console.Write("Введите сообщение: ");
                //string message = Console.ReadLine();
                byte[] data = Encoding.Unicode.GetBytes(textBox1.Text);
                stream.Write(data, 0, data.Length);
            }
        }
 
        // получение сообщений
        private void ReceiveMessage()
        {
            while (true)
            {
                try
                {
                    byte[] data = new byte[64]; // буфер для получаемых данных
                    StringBuilder builder = new StringBuilder();
                    int bytes = 0;
                    do
                    {
                        bytes = stream.Read(data, 0, data.Length);
                        builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                    }
                    while (stream.DataAvailable);
 
                    string message = builder.ToString();
                    richTextBox1.AppendText(message);
                    //Console.WriteLine(message + "\n");//вывод сообщения
                }
                catch
                {
                    Console.WriteLine("Подключение прервано!"); //соединение было прервано
                    Console.ReadLine();
                    Disconnect();
                }
            }
        }
 
        static void Disconnect()
        {
            if (stream != null)
                stream.Close();//отключение потока
            if (client != null)
                client.Close();//отключение клиента
            //Environment.Exit(0); //завершение процесса
        }
    }
}
Вот и архив с этим примером

Суть такая что на консоли клиента и сервера этот пример работает
как только код перегнать на сервер, и Winform клиент то пример не работает, циклиться к зависанию
явно что то не хватает , я пробывал решить, но не получилось ходил по кругу , как не крути не получаеться
Надеюсь кто то знает , то его не хватает в этом коде товарищи?
Вложения
Тип файла: rar Winform_Winform_Chat.rar (68.3 Кб, 315 просмотров)
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.06.2016, 18:21
Ответы с готовыми решениями:

Клиент-сервер. Чат на виртуальном сервере
Здравствуйте. Подскажите пожалуйста как реализовать чат клиент-сервер, если установить сервер на виртуальную машину, да так чтобы он...

Как пишется Клиент-Сервер (чат)?
Добрый день всем!!! Задали написать чат!!! Если честно,то не знаю вообще как написать!!! Подскажите книжку,с помощью которой можно...

Книги о программировании TCP/IP (Клиент-сервер)
Всем привет! Посоветуйте книги (На Русском языке) о программировании TCP/IP на С# Желательно Начальный и средний уровни. Хотя не откажусь...

33
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
30.06.2016, 19:05
Почему бы ему не циклить?
C#
1
2
3
4
5
6
7
8
        private void SendMessage()
        {
            while (true)
            {
                byte[] data = Encoding.Unicode.GetBytes(textBox1.Text);
                stream.Write(data, 0, data.Length);
            }
        }
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
30.06.2016, 22:12  [ТС]
я проверял уберал вот так
зависает тут что то глубже
C#
1
2
3
4
5
6
7
private void SendMessage()
        {
            
                byte[] data = Encoding.Unicode.GetBytes(textBox1.Text);
                stream.Write(data, 0, data.Length);
            
        }
0
132 / 82 / 29
Регистрация: 01.10.2014
Сообщений: 263
30.06.2016, 23:47
GENDALF_ISTARI Бесконечные циклы при получении и отправке грузят как минимум одно ядро вашего процессора на 100%.
Используйте асинхронные методы. writeasync и readasync.
Здесь можно посмотреть простенький пример.
1
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
01.07.2016, 07:14
Цитата Сообщение от GENDALF_ISTARI Посмотреть сообщение
я проверял уберал вот так
зависает тут что то глубже
Нет, не зависает.
Но глючит:
Code
1
2
3
4
5
6
7
Сервер запущен. Ожидание подключений...
sdfsdfssdfsdfs вошел в чат
sdfsdfssdfsdfs:
 вошел в чат
:
 вошел в чат
:
Чтобы не глючило, сообщения надо разделять не через while (Stream.DataAvailable), а как-то понадёжнее.
К примеру, читать посимвольно и ждать символа разделителя (ну и отправлять его, соответственно).
Иначе выходит, что имя и сообщение склеивается в один пакет.
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
01.07.2016, 07:35  [ТС]
Нужно тогда так пример , но я пока не проверял)))
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string name;
string msg;
 
//str склеено сообщение в цикле
string[] mass_str=str.Slip(':');
for(int i=0;i<mass_str.linght;i++)
{
    if(mass_str[i]==":")
{
   name +=mass_str[i]
}
else
{
   msg +=mass_str[i];
}
}
 
//name имя клиента 
//msg сообщение
а вот как выводить , надо задерживать вывод ?
а как ?
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
01.07.2016, 08:19
Вот мой вариант отправки и чтения:
Немного кривовато (лучше было бы использовать BinaryReader), но всю программу я переписывать не хочу
C#
1
2
3
4
5
        private void SendMessage(string value)
        {
            byte[] data = Encoding.Unicode.GetBytes(value + '\0');
            stream.Write(data, 0, data.Length);
        }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        private string GetMessage()
        {
            byte[] data = new byte[2]; // буфер для символа
            StringBuilder builder = new StringBuilder();
            for (; ; )
            {
                Stream.Read(data, 0, 2);
                char c = BitConverter.ToChar(data, 0);
                if (c == '\0')
                    break;
                builder.Append(c);
            }
            return builder.ToString();
        }
+ Для избавления от "зависания", надо в ReceiveMessage() после Disconnect(); добавить return;.
Я ещё некоторые мелочи менял, поэтому вот архив:
Вложения
Тип файла: rar Winform_Winform_Chat_fixes_by_Vort.rar (86.8 Кб, 266 просмотров)
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
01.07.2016, 11:35  [ТС]
К стати Vort_
если ты заметил есть там функция в объекте ServerObject.cs

C#
1
2
3
4
5
6
7
8
9
10
11
12
// трансляция сообщения подключенным клиентам
        protected internal void BroadcastMessage(string message, string id)
        {
            byte[] data = Encoding.Unicode.GetBytes(message);
            for (int i = 0; i < clients.Count; i++)
            {
                if (clients[i].Id != id) // если id клиента не равно id отправляющего
                {
                    clients[i].Stream.Write(data, 0, data.Length); //передача данных
                }
            }
        }
если изменить так ей, где id будет равным
C#
1
2
3
4
5
6
7
8
9
10
11
12
// трансляция сообщения подключенным клиентам
        protected internal void BroadcastMessage(string message, string id)
        {
            byte[] data = Encoding.Unicode.GetBytes(message);
            for (int i = 0; i < clients.Count; i++)
            {
                if (clients[i].Id == id) // если id клиента не равно id отправляющего
                {
                    clients[i].Stream.Write(data, 0, data.Length); //передача данных
                }
            }
        }
тогда можно слать сообщения только клиенту что шлет сообщение серверу
получается индивидуальная обработка

Мало того если клиент будет слать сообщения сложного характера ))
например
autorize|Колян|1234
а точней код такой у клиента
"autorize|"+text1.Text+"|"+text2.Tex t

и написать так в серверу что приймет это сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string[] msg_array_get_client=msg.Split('|');
//Авторизация
if(msg_array_get_client[0]=="autorize")
{
     if(msg_array_get_client[1]=="Колян" && msg_array_get_client[1]=="1234")
     {
           //отправляем клиенту ответ входа
     }
}
//Чат для чата клиент отсылать будет "chat|Колян"+"|"+text2.Text
if(msg_array_get_client[0]=="chat")
{
     Console.WriteLine("Клиент msg_array_get_client[1]: "+msg_array_get_client[2])
    //Отправка клиентам
}
//Данные личные
if(msg_array_get_client[0]=="informer")
{
}
Можно сделать свичем
C#
1
2
3
4
5
6
7
8
9
10
switch(msg_array_get_client[0])
case "autorize":
        //код и так далее..
     break;
case "chat":
         //код и так далее..
     break;
default:
        Console.WriteLine("Сообщение не обработано отвергнуто сервером!");
break;
В основном эти примеры где сообщение переключает
дает ответ серверу , либо клиент в чате пишется
либо авторизируеться , либо какие то личные данные он взаемодействует
Еще применить и шифровку сообщений например RSA
то вообще замечательно , короче клевая штука )))

Добавлено через 4 минуты
Моя задача чтоб код был универсальный
чтоб Консоль сервер + Winform клиент
и можно было как в чате писать , так и переключиться на другое делать
ну этот вопрос понятен , главное код сделать так чтоб
был лояльный к таким делам))))

потому что примеры какие я нашел либо чат , либо индивидуальная обработка
и в цикле они как то не совместимы

Добавлено через 8 минут
Вообще наверное я с нуля код напишу похожий на этот
но другой, без protected internal , аналогия как ASP на объектах, что такое попробую ))
ну пока этот надо решить код
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
01.07.2016, 13:54
Вариант со Split, конечно, возможен.
Но мне кажется, что лучше делать уже по-нормальному:
Использовать TLV и BinaryReader/Writer.
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
01.07.2016, 23:56  [ТС]
А то есть по индитификатору определять что за данные)

Добавлено через 7 часов 45 минут
Смотрел я гуглил BinaryReader
не пойму а как это теги индитификатора
там не за что заципиться ?
C#
1
2
3
NetworkStream NWS = cl.GetStream();
BinaryReader R = new BinaryReader(NWS); //принятие
BinaryWriter W = new BinaryWriter(NWS); //отправка
И где же тут индитификаторы ?
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
02.07.2016, 09:05
Протокол нужно разрабатывать самостоятельно.
BinaryReader лишь позволяет упростить чтение наиболее часто используемых типов данных.

К примеру, можно выделить 1 байт на тип, 2 байта на размер и {размер} байтов на данные.
Тогда, для чтения надо сделать вот так:
C#
1
2
3
int type = br.ReadByte();
int size = br.ReadUInt16();
byte[] data = br.ReadBytes(size);
Поставить if/switch по типу и завернуть это в цикл.
Затем data можно также читать через BinaryReader:
C#
1
BinaryReader br2 = new BinaryReader(new MemoryStream(data));
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
02.07.2016, 11:59  [ТС]
Привет переделал
но пишет что поток не доступен для чтения
когда сообщение отправляет клиент все нормально
но как сервер шлет ответ клиенту
то выводит поток не доступен для чтения
так и не нашел что это

Я это клепал на Visual Studio 2010

Вот посмотри В классе Server_Connect.cs отправка сервера
в этом проекте что прикрепил
Вложения
Тип файла: rar Server_Test_1.rar (188.3 Кб, 58 просмотров)
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
02.07.2016, 15:28
BinaryWriter после своего уничтожения уносит за собой и поток.
Поэтому его лучше создавать в самом начале и затем всё время использовать:
C#
1
2
3
4
                client.Connect(Get_IP, Get_Port); //Подключаемся
                Stream = client.GetStream(); //создаем поток
                bw = new BinaryWriter(Stream);
                br = new BinaryReader(Stream);
C#
1
2
3
4
5
        private void SendMessage(string msg)
        {
            byte[] data = Encoding.UTF8.GetBytes(msg);
            bw.Write(data,0,data.Length);
        }
и т.д.

Добавлено через 25 минут
Кстати, с BinaryReader/BinaryWriter строку можно отправить и принять даже проще:
C#
1
2
3
4
        private void SendMessage(string msg)
        {
            bw.Write(msg);
        }
C#
1
2
3
4
        private string GetMessage()
        {
            return br.ReadString();
        }
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
02.07.2016, 21:08  [ТС]
Сделал так как ты говоришь
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using RSA_code;
 
namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        RSA_vs rsa =new RSA_vs();
        private TcpClient client = null;
        private NetworkStream Stream = null;
        private BinaryWriter bw = null;
        private BinaryReader br = null;
 
        private void button1_Click(object sender, EventArgs e)
        {
            
            string msg = string.Empty;
            try
            {
                SendMessage("chat|" + textBox1.Text + "|" + textBox2.Text); //отсылаем
               
                
                //while (true)
                //{
                listBox1.Items.Add(GetMessage());
                //}
                
            }
            catch (Exception ex)
            {
 
                MessageBox.Show("ERROR: "+ex.Message+"\n\nIP: "+Get_IP+"\nPORT: "+Get_Port, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
 
            }
            finally
            {
                Disconnect();
            }
        }
 
        //Загрузка конфига
        private string Get_IP { get; set; }
        private Int32 Get_Port { get; set; }
        private void Loading_file_Config()
        {
            try
            {
                string[] listconf = File.ReadAllLines("Config.ini");
                string ip = rsa.DecryptData(listconf[0]);
                string port = rsa.DecryptData(listconf[1]);
                Get_Port = Convert.ToInt32(port);
                Get_IP = ip;
            }
            catch 
            {
 
                MessageBox.Show("ERROR: Подклюение не установлено!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
 
        }
 
        // отправка сообщений
        private void SendMessage(string msg)
        {
            byte[] data = Encoding.UTF8.GetBytes(msg);
            bw.Write(data,0,data.Length);
            
        }
 
        // отправка сообщений
        private string SendMessage2(string msg)
        {
            byte[] data = Encoding.UTF8.GetBytes(msg);
            string get_msg = string.Empty;
            StringBuilder builder = new StringBuilder();
            using (BinaryWriter writers = new BinaryWriter(Stream))
            {
                writers.Write(data, 0, data.Length);
            }
 
            int bytes = 0;
            using (BinaryReader reader = new BinaryReader(Stream))
            {
                bytes = reader.Read(data, 0, data.Length);
                builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
            }
            get_msg = builder.ToString();
 
            return get_msg; 
        }
 
        // чтение входящего сообщения и преобразование в строку
        private string GetMessage()
        {
            string ms = string.Empty;
            try
            {
                ms = br.ReadString();
            }
            catch (Exception ex)
            {
 
                MessageBox.Show("Подключение прервано!\n\n"+ex.Message,"ОШИБКА",MessageBoxButtons.OK,MessageBoxIcon.Stop); //соединение было прервано
               Disconnect();
            }
           
            return ms;
        }
 
 
        // чтение входящего сообщения и преобразование в строку
        private string GetMessage2()
        {
            
            StringBuilder builder = new StringBuilder();
            string mess = string.Empty;
            try
            {
                byte[] data = new byte[64]; // буфер для получаемых данных
 
                int bytes = 0;
                do
                {
                    bytes = Stream.Read(data, 0, data.Length);
                    builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
                }
                while (Stream.DataAvailable);
 
                mess = builder.ToString();
            }
            catch (Exception ex)
            {
 
                MessageBox.Show("Подключение прервано!\n\n" + ex.Message, "ОШИБКА", MessageBoxButtons.OK, MessageBoxIcon.Stop); //соединение было прервано
                Disconnect();
            }
 
            return mess;
        }
 
        //Отключение клиента
        private void Disconnect()
        {
            if (Stream != null)
            {
                Stream.Close();
            }
            if (client!=null)
            {
               client.Close(); 
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Loading_file_Config();
 
            try
            {
                client = new TcpClient();
                client.Connect(Get_IP, Get_Port); //Подключаемся
                Stream = client.GetStream(); //создаем поток
                bw = new BinaryWriter(Stream); //Поток отправки
                br = new BinaryReader(Stream); //поток чтения
            }
            catch (Exception ex)
            {
                
                MessageBox.Show("ERROR: "+ex.Message,"ERROR",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
            }
          
        }
    }
}
началась другая проблема
Чтения посл конца потока не возможно
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
03.07.2016, 09:32
Цитата Сообщение от GENDALF_ISTARI Посмотреть сообщение
началась другая проблема
Чтения посл конца потока не возможно
Проблема вот в этой строчке:
C#
1
listBox1.Items.Add(GetMessage());
Клиент ждёт чего-то от сервера.
Но сервер вместо отправки данных просто закрывает соединение.
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
03.07.2016, 10:25  [ТС]
Я та понял что закраивает только не пойму почему и где ?
в роди нету кода закрытия странно , по ковыряю может где то собака зарыта
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
03.07.2016, 10:51
Цитата Сообщение от GENDALF_ISTARI Посмотреть сообщение
Я та понял что закраивает только не пойму почему и где ?
Вот этот цикл отрабатывает только один раз:
C#
1
2
3
                while (exit < 1)
                {
                    exit++;
После чего выполняется участок
C#
1
2
3
4
            finally
            {
                // в случае выхода из цикла закрываем ресурсы
                server.RemoveConnection(this.Id);
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
03.07.2016, 12:38  [ТС]
А то есть он должен быть
C#
1
2
3
while (true)
                {
                   }
Без перерыва , но нужно как то его приостановить
а то он штампует прием постоянно , не думал что это повлияет
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
03.07.2016, 12:49
Тут два вопроса.
Во-первых: когда разрывать соединение. Можно сделать у клиента команду "exit" и разрывать соединение по её приёму.
Во-вторых: в каком порядке сервер и клиент должны обмениваться сообщениями. Я вижу два варианта: 1. Сервер всегда слушает на приём. Приходит команда, он её обрабатывает и шлёт ответ, но по своей инициативе никаких данных не отправляет. 2. И сервер и клиент могут в любой момент как отправить сообщение, так и принять. Такой вариант сложнее, для него, скорее всего, нужно делать два треда (на приём и на отправку). Плюс надо как-то помечать пары запросов-ответов, чтобы знать на какой запрос был прислан какой ответ.
1
 Аватар для GENDALF_ISTARI
16 / 33 / 19
Регистрация: 20.08.2013
Сообщений: 740
04.07.2016, 04:41  [ТС]
Тогда нужно
сразу и отправка и прием от сервера
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 //Отпрака серверу сообщения каждый раз создав поток и клиента
        //учитывая и получения
        private string Send_Connect_one(String Message)
        {
            string ms = string.Empty;
            try
            {                
               
                client = new TcpClient();
                // Переводим наше сообщение в ASCII, а затем в массив Byte.
                Byte[] data = System.Text.Encoding.UTF8.GetBytes(Message);
                
                client.Connect(Get_IP, Get_Port); //Подключаемся
                Stream = client.GetStream(); //создаем поток
                bw = new BinaryWriter(Stream); //Поток отправки
                br = new BinaryReader(Stream); //поток чтения
 
                bw.Write(data, 0, data.Length); //отправляем серверу
                
                ms = br.ReadString(); //получаем от сервера ответ
                
                Disconnect(); //Выходим с потока и клиента созданого
            }
            catch (Exception ex)
            {
                
                MessageBox.Show("Отправка прием ошибка: "+ex.Message,"ERROR",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
            }
            return ms;
        }
 
 
 
        //Отключение клиента
        private void Disconnect()
        {
            if (Stream != null)
            {
                Stream.Close();
            }
            if (client!=null)
            {
               client.Close(); 
            }
        }
Добавлено через 8 минут
А у сервере
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
                while (exit<1)
                {
                    //exit++;
                    
                    string msg = string.Empty;
                    string[] users = message.Split('|');
 
                    //Console.WriteLine("Test: " + message);
 
                    //Авторизация
                    if (users[0] == "autorize")
                    {
 
                    }
 
                    //Чат
                    if (users[0] == "chat")
                    {
                        try
                        {
                            msg = String.Format("{0}: {1}", users[1], users[2]);
                            Console.WriteLine(msg);
                            server.BroadcastMessage(message, this.Id);
                            exit = 1; //останавливаем
 
                        }
                        catch
                        {
                            msg = String.Format("{0}: покинул чат", users[1]);
                            Console.WriteLine(msg);
                            server.BroadcastMessage("chat|" + users[1] + "|покинул чат", this.Id);
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                
            }
            finally
            {
               // в случае выхода из цикла закрываем ресурсы
                 server.RemoveConnection(this.Id);
                 Close();
            }
 
        }
Все равно пишет : Чтение после конца потока не возможно

Добавлено через 5 минут
Вообще вот этот код что ты посоветовал

C#
1
 ms = br.ReadString(); //получаем от сервера ответ
Из за него ошибка
его нужно изменить , или дописать что то ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.07.2016, 04:41
Помогаю со студенческими работами здесь

Tcp Сервер - Клиент обмен данными
Ситуация такая: есть Tcp клиент и сервер для xna игры. Реализован обмен объектами, которые содержатся в единой библиотеке. Объекты...

TCP/IP клиент-сервер не могу подключиться
создал клиент-сервер когда клиенту поставил подключение через &quot;127.0.0.1&quot;и через порт 80 все работало а когда через мой ip 93.171.243.89...

Поиск по маске на клиент сервер tcp
Я знаю что в обычном случае можно сделать поиск через void GetFiles() { //список файлов с расширением txt диска C: ...

Как создать многопользовательский чат (Сервер-клиент)
Как создать многопользовательский чат(Сервер-клиент)?

Довести до ума чат клиент/сервер, написанный по видеоинструкции
С помощью видео из Youtube-а я написал код для сервера и самого клиента, но вот как довести до ума - без понятия :( Помогите, пожалуйста)))...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru