Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
2 / 2 / 1
Регистрация: 09.01.2015
Сообщений: 382
1

Работа с Socket и перегруз

08.08.2018, 23:25. Показов 550. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день ! Недавно наткнулся на статью в которой говорилось о том что если запустить бесконечный цикл в другом потоке то возрастает загрузка ЦП. Решил посмотреть у себя и действительно после коннекта загруз цп с 3% поднялся до 50 % . Как я понял решается это проблема Слипом . Только вот не могу понять как мне его прикрутить ((
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
188
189
190
191
192
193
194
195
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Timers;
 
namespace Client
{
    public class SocetConnect
    {
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> connected;
        protected virtual void Connected(net.SocketEventArgs e) { if (connected != null) connected(this, e); }
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> closed;
        protected virtual void Closed(net.SocketEventArgs e) { if (closed != null) closed(this, e); }
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> ioError;
        protected virtual void IoError(net.SocketEventArgs e) { if (ioError != null) ioError(this, e); }
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> incomingData;
        protected virtual void IncomingData(net.SocketEventArgs e) { if (incomingData != null) incomingData(this, e); }
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> outgoingData;
        protected virtual void OutgoingData(net.SocketEventArgs e) { if (outgoingData != null) outgoingData(this, e); }
        //---------------------------------------------------------------------------------------------------
        public event EventHandler<net.SocketEventArgs> needNOP;
        protected virtual void NeedNOP(net.SocketEventArgs e) { if (needNOP != null) needNOP(this, e); }
        //---------------------------------------------------------------------------------------------------
 
        Socket socket = null;
        public string unpack = "";
        public string unpacket = "null";
        UnpackChat unpackchat = new UnpackChat();
        UnpackGame unpackgame = new UnpackGame();
        public Thread _thread;
        public bool isConnected;
        System.Timers.Timer time;
 
 
        public void Connect(net.ServerObject serverObject)
        {
            try
            {
                this.unpacket = serverObject.unpack; // Тип распаковки принятых данных 
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Создаем Tcp socket
                IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(serverObject.host), serverObject.port); // Создаем точку подключения 
                socket.ReceiveBufferSize = 65535; // Размер буфера сокета , куда приходят данные 
                socket.Connect(ipPoint); // Коннектимся 
                _thread = new Thread(ReceiveData);
                _thread.IsBackground = true;
                _thread.Start();
                isConnected = true;
                NopTimer();
                Connected(new net.SocketEventArgs("<Connected/>")); // Событие то-что законнектились 
                
            }
        catch (Exception e)
            {
 
            }
        }
 
        public void Disconnect()
        {
            //  socket.Shutdown(SocketShutdown.Both); // Приостанавливаем прием/передачу
            //  socket.Disconnect(true); // Отключаем сокет 
            /*    socket.Close();
                socket.Dispose();
                //  socket = null;
          
             Closed(new net.SocketEventArgs("<Disconnected/>")); // Событие дисконекта */
            if ((time != null)&&(time.Enabled))
            {
                time.Stop();
                time.Dispose();
            }
            if (isConnected)
            {
                _thread.Interrupt();
                socket.Shutdown(SocketShutdown.Both); // Приостанавливаем прием/передачу   
                socket.Disconnect(true); // Отключаем сокет 
                isConnected = false;
                Closed(new net.SocketEventArgs("<Disconnected/>")); // Событие дисконекта 
            }
        }
 
        public bool Status()
        {
            if (socket != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 
        public void SendData(string data) // Передача 
        {
 
            time.Stop();
            time.Start();
            byte[] array = Encoding.UTF8.GetBytes(data);
            byte[] big_array = new byte[array.Length + 1];
            Array.Copy(array, 0, big_array, 0, array.Length);
            big_array[big_array.Length - 1] = 0x00;
            socket.Send(big_array);
            OutgoingData(new net.SocketEventArgs(data));
        }
 
        public void ReceiveData() // Прием 
        {
            byte[] data = new byte[256]; // Размер буфера 
            int bytes = 0; // Кол-во считанных байт 
            string packet = ""; // Строка для хранения пакета 
            List<byte> builder = new List<byte>();
 
            while (socket.Connected)
            {
                while (socket.Available > 0)
                {
                    bytes = socket.Receive(data, data.Length, SocketFlags.None);
                    if (bytes > 0)
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            builder.Add(data[i]);
                        }
                    }
 
                }
 
                if (builder.Count > 1)
                {
                    if (builder[builder.Count - 1] == Convert.ToChar(0x00)) // Если у нас что - то есть и оно заканчивается на 0x00 
                    {
 
                        packet = Encoding.UTF8.GetString(builder.ToArray(), 0, builder.Count);
                        packet = packet.Replace("\x0D" + "\x0A", "");
 
                         transiver(packet);
                        builder.Clear();
                        packet = ""; // Обнуляем 
                    }
                }
 
            }
        }
 
        public void transiver(string msg)
        {
            string[] packets = msg.Split(new char[] { Convert.ToChar(0x00) }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string s in packets) // перебираем пакеты 
            {
                switch (this.unpacket)
                {
 
                    case "GAME":
                        IncomingData(new net.SocketEventArgs(unpackgame.convert(s))); // вызов события 
                        break;
                    case "CHAT":
                        string[] p = s.Split(new char[] { Convert.ToChar(0x0D), Convert.ToChar(0x0A) }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string s0 in p)
                        {
                            IncomingData(new net.SocketEventArgs(unpackchat.convert(s0))); // вызов события 
                        }
                        break;
                    default:
                        IncomingData(new net.SocketEventArgs(s)); // вызов события 
                        break;
                }
            }
        }
 
        public void NopTimer()
        {
            time = new System.Timers.Timer(45000);
            time.Elapsed += NopDzin;
            time.AutoReset = true;
            time.Enabled = true;
            time.Start();
        }
 
 
        public void NopDzin(Object source, ElapsedEventArgs e)
        {
            NeedNOP(new net.SocketEventArgs("<NeedNOP/>"));
        }
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.08.2018, 23:25
Ответы с готовыми решениями:

Socket и работа с ним!
Вот часть кода public void SendMessageFromSocket(int port, string IPadd, string comm) ...

Работа с listen socket
Здравствуйте. Появилась необходимость таскать данные от службы к приложению и обратно по TCP/IP....

WinCE работа с Socket через ActiveSync
Всем добрый день! Прошу помощи. Перехожу сразу к делу: Есть ТСД c WinCE, ставим на подложку,...

Socket перенаправить в другой Socket
Доброго всем. Что делаю: Принимаю запрос, который нужно перенаправить к удаленному компьютеру....

9
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
09.08.2018, 12:32 2
Цитата Сообщение от Marchcat Посмотреть сообщение
C#
1
for (int i = 0; i < bytes; i++) { builder.Add(data[i]); }
ужс....

Цитата Сообщение от Marchcat Посмотреть сообщение
Как я понял решается это проблема Слипом .
Ни разу.

Цитата Сообщение от Marchcat Посмотреть сообщение
поднялся до 50 %
дьі зачем проверять Available, которьій явно будет пустой? Вот у вас и молотит, пока не прилетит сообщение.
0
2 / 2 / 1
Регистрация: 09.01.2015
Сообщений: 382
09.08.2018, 16:36  [ТС] 3
Цитата Сообщение от Wolfdp Посмотреть сообщение
дьі зачем проверять Available, которьій явно будет пустой? Вот у вас и молотит, пока не прилетит сообщение.
А как вы тогда предлагаете отслеживать приход сообщения ?

Добавлено через 3 минуты
Цитата Сообщение от Wolfdp Посмотреть сообщение
Сообщение от Marchcat
C#Выделить код
1
for (int i = 0; i < bytes; i++) { builder.Add(data[i]); }
ужс....

А чем вам не понравилось добавление в Лист байт ?
0
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
09.08.2018, 17:18 4
Цитата Сообщение от Marchcat Посмотреть сообщение
А как вы тогда предлагаете отслеживать приход сообщения ?
Recived отработает только тогда, когда на порт поступят данньіе. Просто ждите его отработки, чейкайте сколько считали и отправляйте данньіе дальше на обработку.

Цитата Сообщение от Marchcat Посмотреть сообщение
А чем вам не понравилось добавление в Лист байт ?
Побайтово? Почему не побитово, чего мелочится? Вообще тут логичнее Memory заюзать. А еще логичнее вообще повесить поверх TextReader, и не изобретать велосипед. Или вообще обьявить базовый меседжер, заюзать бинарную сериализацию, и радоватся жизни (трафик правда подскочит). Можно оставить и list.Add, тут єто не главная проблема.
0
2 / 2 / 1
Регистрация: 09.01.2015
Сообщений: 382
09.08.2018, 17:27  [ТС] 5
C#
1
2
3
4
5
6
7
8
9
10
11
12
               while (socket.Available > 0)
                {
                    bytes = socket.Receive(data, data.Length, SocketFlags.None);
                    if (bytes > 0)
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            builder.Add(data[i]);
                        }
                    }
 
                }
если скорость передачи не провалится или не закончится пакет из этого цикла не выйдет .
Т.е пока в буффере есть что забирать . я забираю
C#
1
while (socket.Available > 0)
и если пусто то мы проскакиваем на обработку .
а вот
C#
1
            while (socket.Connected)
Он же while(true) пока существует сокет и подвешивает мне все . но чтение по таймеру я делать не хочу . Читал что на плюсах народ выходил тем что просто угонял в Sleep(1) . и сразу в разы падала загруженность проца .
0
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
09.08.2018, 18:50 6
убирите цикл, while (socket.Available > 0) он там не нужен от слова "совсем".

Еще раз Recived отработает только тогда, когда на порт поступят данньіе. До это поток будет спать, не дергая процессор. Проверять "если данные" не нужно. Если поток закроют, то Recived вернет 0. Ну и оберните в try-catch, чтобы отлавливать разрыв связи.

"Решение" через Sleep -- УГ, просто замаскируете проблему, причем (1) на самом деле даст задержку в 100, и будет тоже выжирать CPU в никуда.
0
2 / 2 / 1
Регистрация: 09.01.2015
Сообщений: 382
09.08.2018, 18:58  [ТС] 7
Я просто вас не понимаю . Покажите наглядно ( кодом если возможно ) . просто я делал
C#
1
if (socket.Available > 0)
результат тот же

Добавлено через 4 минуты
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
       public void ReceiveData() // Прием 
        {
            byte[] data = new byte[256]; // Размер буфера 
            int bytes = 0; // Кол-во считанных байт 
            string packet = ""; // Строка для хранения пакета 
            List<byte> builder = new List<byte>();
 
            while (socket.Connected)
            {
              //  while (socket.Available > 0)
               // {
                    bytes = socket.Receive(data, data.Length, SocketFlags.None);
                    if (bytes > 0)
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            builder.Add(data[i]);
                        }
                    }
 
              //  }
 
                if (builder.Count > 1)
                {
                    if (builder[builder.Count - 1] == Convert.ToChar(0x00)) // Если у нас что - то есть и оно заканчивается на 0x00 
                    {
 
                        packet = Encoding.UTF8.GetString(builder.ToArray(), 0, builder.Count);
                        packet = packet.Replace("\x0D" + "\x0A", "");
 
                         transiver(packet);
                        builder.Clear();
                        packet = ""; // Обнуляем 
                    }
                }
            }
        }
???
0
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
09.08.2018, 19:09 8
Цитата Сообщение от Marchcat Посмотреть сообщение
if (socket.Available > 0)
нет, проверять буфер вообще не нужно.

Цитата Сообщение от Marchcat Посмотреть сообщение
C#
1
// while (socket.Available > 0)
Оно. Если и после єтого сьедает 50% (кстати, при двух подключениях должно вообще бьіло улетать под 100%), то нужно смотреть дальше.
0
2 / 2 / 1
Регистрация: 09.01.2015
Сообщений: 382
09.08.2018, 19:16  [ТС] 9
Ура !!! Упало . до 14 , но при закрытии периодически вылетают ошибки по
C#
1
bytes = socket.Receive(data, data.Length, SocketFlags.None);
Т.е когда я закрываю при приеме , выскакивает ошибка
0
Эксперт .NET
1696 / 1325 / 316
Регистрация: 15.06.2012
Сообщений: 5,045
Записей в блоге: 3
09.08.2018, 19:20 10
Цитата Сообщение от Wolfdp Посмотреть сообщение
оберните в try-catch, чтобы отлавливать разрыв связи.
и погуглите правильное закрьітие сокета.
1
09.08.2018, 19:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.08.2018, 19:20
Помогаю со студенческими работами здесь

Невозможно создать Socket: Socket sock = new Socket(someHostString,somePortInt);
Народ! Помогите пожалуйста. Вся красота губится на exception что выскакивает в момент создания...

Работа с socket' а ми
Есть код скачанный с интернета но он написан на VC++ (6) и не компилируется на VC++ (10) пишет...

Перегруз
Можете помочь ошибку C2995, как правильно перегружать #include&quot;stdafx.h&quot; #include&lt;iostream&gt; ...

Работа с Socket(ами)
Всем добрый день! В данный момент разбираюсь со следующей вещью - хочу используя класс Socket,...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru