Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/21: Рейтинг темы: голосов - 21, средняя оценка - 4.71
3 / 3 / 0
Регистрация: 18.10.2012
Сообщений: 18
.NET 3.x

Как грамотно реализовать disconnect, чтобы можно было соединяться с сокетом по той же ссылке

19.11.2012, 22:06. Показов 4314. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет c# сообщество

уже 3 вечера бьюсь с одной проблемой.. совсем беда
пишу клиент\ северное приложение на c#
все работает. и почти везде грамотно обрабатывается
Но, когда клиент работает, а сервер закрывается, то клиент,естественно , должен делать disconnect(от него сыпятся error)
но еще больше error сыпется от повторного connect

после этого, если воскресить сервер, то клиент может подключится к нему (error сыпаться перестанут) а может превратиться в кирпич.. на свое усмотрение.

нашел по теме статью

но там нет примеров реализации. и что то как то не верится что в самом .net есть с этим беда.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
 
namespace clientSocket
{
    public delegate void RecieveDataHandler(object sender, Tuple<byte[], int> e);
    public delegate void ConnectHandler(object sender, int sessionID);
 
    public class ClientSocket
    {
        /**************************************************
         * Объявления
         *************************************************/
        private readonly Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private readonly byte[] Buffer = new byte[20480000];
        private readonly IPEndPoint endPoint;
        public bool Connected { get; set; }
 
        /**************************************************
         * Функции
         *************************************************/
        public ClientSocket(string Address, int Port)
        {
            endPoint = new IPEndPoint(IPAddress.Parse(Address), Port);
        }
 
        public int Connect()
        {
            int retResult = 0;
            try
            {
              //  clientSocket.
 
                clientSocket.Connect(endPoint);
                clientSocket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, client_DataReceived, clientSocket);
            }
            catch (SocketException e)
            {
                retResult = e.ErrorCode;
            }
            catch(Exception e){}
            Connected = retResult == 0;
            return retResult;
        }
 
        public void Disconnect()
        {
            //clientSocket.Shutdown(SocketShutdown.Both);
            Connected = false;
           // clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Disconnect(true);
            clientSocket.Dispose();
            
            
              
        }
 
 
        public void SendToServer(byte[] sendData)
        {
           clientSocket.Send(sendData);
 
        }
 
        private void client_DataReceived(IAsyncResult ar)
        {
            try
            {
                Socket curSock = (Socket)ar.AsyncState;
                int bytesRead = curSock.EndReceive(ar);
 
                if (bytesRead > 0)
                {
                    OnRecieveData(Buffer, bytesRead);
                    curSock.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, client_DataReceived, clientSocket);
                }
                else
                    OnServerDisconnect();
            }
            catch (Exception ex) {  }
        }
 
        /**************************************************
         * События
         *************************************************/
        public event RecieveDataHandler RecieveData;
        public event ConnectHandler ServerDisconnect;
 
        protected virtual void OnRecieveData(byte[] buff, int bread)
        {
            RecieveData(this, new Tuple<byte[], int>(buff, bread));
        }
 
        protected virtual void OnServerDisconnect()
        {
      //      Connected = false;
        //    ServerDisconnect(this, 0);
            Disconnect();
       //     clientSocket.Close();
           // clientSocket.Shutdown(SocketShutdown.Both);
        }
    }
}
использование

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
 client = new ClientSocket("127.0.0.1", 53535);
 
 client.RecieveData += client_DataReceived;
 
                  do{
                    res = client.Connect();
 
                    if (res == 0)
                    {
                        _notifyIconConnected();
                        SendMessToServer("%Ok.StartInitialize");// подтверждение что все хорошо и старт инициализации интерфеййса сервера*/
 
                    }
                    else 
                    {
                        Thread.Sleep(1000);
                    }
                    }
                    while(res!=0);
и вот вопрос- Как грамотно реализовать disconnect, чтобы потом с сокетом можно было соединяться по той же ссылке?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.11.2012, 22:06
Ответы с готовыми решениями:

Как сделать чтобы кликая по ссылке можно было открыть рисунок в программе "ACDSee"?
Имеется Access 2016 Ленточная форма. На форме для отображения рисунка, используется элемент &quot;Рисунок&quot;. Сам рисунок...

Как реализовать систему сокетов на сервере? Чтобы можно было с любого компьютера подключиться к этому сокету?
Всем привет. Как реализовать систему сокетов на сервере? Чтобы можно было с любого компьютера подключиться к этому сокету, отправить туда...

Определить функцию-член в наследнике так, чтобы её можно было вызвать только по ссылке на базовый класс
Пусть дан абстрактный класс A class A { public: void virtual method() const = 0; }; Определите класс B - наследник от...

3
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
20.11.2012, 10:19
Цитата Сообщение от Shan-S Посмотреть сообщение
Как грамотно реализовать disconnect, чтобы потом с сокетом можно было соединяться по той же ссылке?
После вызова Disconnect(true) не вызывайте Dispose - он делает объект непригодным для дальнейшего использования.

Ответы на остальные вопросы в личке.
0
3 / 3 / 0
Регистрация: 18.10.2012
Сообщений: 18
21.11.2012, 01:28  [ТС]
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
//using Protocol;
 
namespace AdminEyeServer
{
    public delegate void RecieveDataHandler(object sender, byte[] data);
    public delegate void ConnectHandler(object sender, string name);
 
    public class Client
    {
        public Socket ClientSocket;
        public string Name;
 
        public Client(string name, Socket client)
        {
            this.ClientSocket = client;
            this.Name = name;
 
        }
 
 
    }
 
    public class SocketServer
    {
        /// <summary>
        /// Вызывается когда сервер получает данные
        /// </summary>
        public event RecieveDataHandler RecieveData;
 
        /// <summary>
        /// Вызывается когда сервер принимает подключение от клиента
        /// </summary>
        public event ConnectHandler ClientConnect;
 
        /// <summary>
        /// Вызывается когда клиент разрывает соединение с сервером
        /// </summary>
        public event ConnectHandler ClientDisconnect;
 
        private readonly Socket _server = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
        private readonly byte[] Buffer = new byte[20480000];
        /// <summary>
        /// Список подключенных клиентов
        /// </summary>
        public List<Client> Clients = new List<Client>();
 
        private readonly IPEndPoint endPoint;
 
        /// <summary>
        /// Конструктор класса сервера
        /// </summary>
        /// <param name="port">Номер порта</param>
        public SocketServer(int port)
        {
            endPoint = new IPEndPoint( IPAddress.Any, port);
        }
 
        /// <summary>
        /// Начать прослушивание порта
        /// </summary>
        /// <returns>Возвращает 0, или код ошибки</returns>
        public int StartListen()
        {
            int result = 0;
            try
            {
                _server.Bind(endPoint);
                _server.Listen(64);
                _server.BeginAccept(server_ConnectionAccepted, _server);
            }
            catch (SocketException e)
            {
                result = e.ErrorCode;
            }
            return result;
        }
 
        /// <summary>
        /// Остановить прослушивание
        /// </summary>
        public void StopListen()
        {
            foreach (Client client in Clients)
            {
                client.ClientSocket.Shutdown(SocketShutdown.Both);
            }
        }
 
        /// <summary>
        /// Отправить клиенту
        /// </summary>
        /// <param name="name">Имя клиента</param>
        /// <param name="sendData">Данные для отправки</param>
        public void SendToClient(string name, byte[] sendData)
        {
            Client client = Clients.First(c => c.Name.Equals(name));
            if(client != null)
                client.ClientSocket.Send(sendData);
        }
 
        /// <summary>
        /// Отправить всем
        /// </summary>
        /// <param name="sendData">Данные для отправки</param>
        public void SendToAll(byte[] sendData)
        {
            foreach (Client client in Clients)
            {
                client.ClientSocket.Send(sendData);
            }
        }
 
        private void server_ConnectionAccepted(IAsyncResult ar)
        {
            Socket handler = _server.EndAccept(ar);
            handler.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, server_DataReceived, handler);
            _server.BeginAccept(server_ConnectionAccepted, null);
            OnClientConnect(handler.GetHashCode().ToString(), handler);
            
        }
 
 
        private void server_DataReceived(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                int bytesRead = handler.EndReceive(ar);
                if (bytesRead > 0)
                {
                    DataReceived(Buffer);
                    handler.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, server_DataReceived, handler);
                }
                else
                {
                    handler.Shutdown(SocketShutdown.Both);
                    Clients.RemoveAll(c => c.ClientSocket.Equals(handler));
                    OnClientDisconnect(handler.GetHashCode().ToString(), handler);
                }
            }
            catch (SocketException e) { }
        }
 
        protected virtual void DataReceived(byte[] buff)
        {
            if(RecieveData != null)
                RecieveData(this, buff);
        }
 
        protected virtual void OnClientConnect(string id, Socket client)
        {
            this.Clients.Add(new Client(id, client));
            if(ClientDisconnect != null)
                ClientConnect(this, id);
        }
 
        protected virtual void OnClientDisconnect(string id, Socket client)
        {
            this.Clients.RemoveAll(c => c.Name.Equals(id));
            if(ClientDisconnect != null)
                ClientDisconnect(this, id);
        }
    }
}
вот сервер, к слову
0
3 / 3 / 0
Регистрация: 18.10.2012
Сообщений: 18
28.11.2012, 06:09  [ТС]
Отвечаю сам на свой вопрос.
1)исправил момент, в том что событие Disconnect у меня не совершалось вообще .)
2) изменил код вызова и сейчас он выглядит как полукостыль

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
   void ConnectToServerInterface(bool newSocket)
            {//connect to server
                try
                {
                    _notifyIconWait();
                    int res; 
 
                    string str = EBC.GetIP();
 
                    if (newSocket == true)
                    {
                        client = new ClientSocket(str, 53535);
                        client.RecieveData += client_DataReceived;
                        client.ServerDisconnect += OnServerDisconnect;
                    }
 
 
                    do
                    {
                        if (newSocket == false)
                        {
                            client = new ClientSocket(str, 53535);
                            client.RecieveData += client_DataReceived;
                            client.ServerDisconnect += OnServerDisconnect;
                        }
 
                        res = client.Connect();
 
                        if (res == 0)
                        {
                            _notifyIconConnected();
                            SendMessToServer("%Ok.StartInitialize");// подтверждение что все хорошо и старт инициализации интерфеййса сервера*/
                            Thread ThreadWork = new Thread(new ThreadStart(Work));
                            ThreadWork.Start();
                        }
                        else
                        {
                            Thread.Sleep(1000);
                        }
                    }
                    while (res != 0);
                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
при первом вызове функции аргумент должен быть +
все последующие -

работает стабильно. пруф от мелкомягких

но осталось ощущение что где то затаился говнокод..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.11.2012, 06:09
Помогаю со студенческими работами здесь

Как сделать чтобы в ссылке на сайт не нужно было прописывать wordpress?
Доброго времени суток всем! Решил создать блог(в этом я чайник:) на движке wordpress, на бесплатном хостинге. Проблема в том что когда я...

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

Реализовать метод setName, чтобы с его помощью можно было устанавливать значение private String name
Вот задача,многие знают откуда она: Реализовать метод setName, чтобы с его помощью можно было устанавливать значение переменной private...

Расскажите пожалуйста идею, как реализовать чтобы по кнопке "изменить" любой текст сразу можно было изменить
Расскажите пожалуйста идею, как реализовать чтобы по кнопке &quot;изменить&quot; любой текст сразу можно было изменить. Ну вот например есть...

Как сделать так, что бы можно было вводить данные в форму и давал вывод в той же форме?
вот сам код! import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Random; import...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru