С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/35: Рейтинг темы: голосов - 35, средняя оценка - 4.69
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21

Работа с сокетами: клиент и сервер в одной программе

22.12.2011, 06:12. Показов 6561. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите как лучше реализовать.
Есть программа №1 она посылает данные другой программе через сокеты. Программа №2 находится в режиме слушателя.

Мне нужно, чтобы после приема пакета программой№2 и некоторых действий, от этой программы по сокетам уходил ответ на программу №1. Как лучше это сделать?
Я наверно глупость сделал, но делал через два слушателя:первая программа отправила пакет и врубается слшатель. вторая приняла, ее слушатель остановился и обработала пакета и отправила пакет, после чего врубила свой слушатель.
Первая приняла пакет, обрабатала, слушатель врубился и повисла.

Я пока думаю через асинхронные сокеты это сделать... Программа№2 всегда должна быть на приеме. А программа№1 работать на прием после первого отосланного пакета.

Подскажите как лучше. Желательно с примера
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.12.2011, 06:12
Ответы с готовыми решениями:

Работа с сокетами: клиент-сервер работает только из под отладки
Пытаюсь осилить сетевое программирование, отойдя чуть дальше простых примеров. В отладчике работает на 50%, а при запуске из консоли не...

Клиент и сервер в одной программе
Здравствуйте. Вот код: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include...

Работа с сокетами, основы клиент-серверного приложения
Нашел простой пример клиент-серверного приложения на C#: Сервер: // SocketServer.cs using System; using System.Text; using...

11
42 / 36 / 2
Регистрация: 18.12.2011
Сообщений: 113
22.12.2011, 15:04
создаешь Socket, назовем его listener)
C#
1
2
3
4
5
6
7
8
9
10
11
12
new Thread(()=>
{
while(true)
{
byte[] buffer = new byte[256];
EndPoint sndr = new EndPoint(0,0);
listener.ReceiveFrom(buffer, out sndr);
Socket sender = /*тут смотря какой протокол юзаешь*/;
sender.Connect(sndr);
sender.Send(Encoding.UTF8.GetBytes("hi, i'm server:)"));
}
}).Start();
+Если протокол tcp, то вместо ресайвФром можно использовать Listen (переводит в режим ожидания подключений) Accept (при коннекте на прослушиваемый порт возвращает сокет соедененный с подключившейся машиной)
Ну а если по нормальному - создаешь поток бесконечно слушающий какой-нибудь порт, в котором при подключении сразу вызываешь функцию обработчик-узла, которая делает еще один поток в котором принимает данные с подключенного пк. Ну и отправляет ответ.
1
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21
23.12.2011, 05:58  [ТС]
Цитата Сообщение от iTheSaboteur Посмотреть сообщение
создаешь Socket, назовем его listener)
C#
1
2
3
4
5
6
7
8
9
10
11
12
new Thread(()=>
{
while(true)
{
byte[] buffer = new byte[256];
EndPoint sndr = new EndPoint(0,0);
listener.ReceiveFrom(buffer, out sndr);
Socket sender = /*тут смотря какой протокол юзаешь*/;
sender.Connect(sndr);
sender.Send(Encoding.UTF8.GetBytes("hi, i'm server:)"));
}
}).Start();
+Если протокол tcp, то вместо ресайвФром можно использовать Listen (переводит в режим ожидания подключений) Accept (при коннекте на прослушиваемый порт возвращает сокет соедененный с подключившейся машиной)
Ну а если по нормальному - создаешь поток бесконечно слушающий какой-нибудь порт, в котором при подключении сразу вызываешь функцию обработчик-узла, которая делает еще один поток в котором принимает данные с подключенного пк. Ну и отправляет ответ.
Проблем в отправки нет. Проблема скорее в приеме.
Одна программа находится в состоянии постоянной прослушки. Вторая отсылает ей пакеты по сокетам. Все хорошо. Возникает проблема когда после обработки, пакеты от первой программой нужно отправить второй программе. Как это организовать?????????????????????
Ставил бесконечную прослушку на двух программах, но на разных портах. Итог: происходит зависание программы
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
23.12.2011, 06:08
Luck999, зачем создавать 2 сокета? По одному можно посылать данные в обе стороны. Так что не надо придумывать велосипед.
А вообще, чтоб программа не висла на ожидании, запускайте прослушку в другом потоке.
1
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21
23.12.2011, 06:13  [ТС]
Цитата Сообщение от body90 Посмотреть сообщение
Luck999, зачем создавать 2 сокета? По одному можно посылать данные в обе стороны. Так что не надо придумывать велосипед.
А вообще, чтоб программа не висла на ожидании, запускайте прослушку в другом потоке.
Можно пример? Нужно запихаю я в тот же сокет новые данные, что делать на приеме на другой стороне?
И как запустить в другой поток? это через thread?
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
23.12.2011, 11:30
Цитата Сообщение от Luck999 Посмотреть сообщение
Можно пример?
Сейчас не могу. Сижу не с домашнего.
Цитата Сообщение от Luck999 Посмотреть сообщение
Нужно запихаю я в тот же сокет новые данные, что делать на приеме на другой стороне?
Socker.Send() - отправка. Socket.Receive() - получение.
Цитата Сообщение от Luck999 Посмотреть сообщение
И как запустить в другой поток? это через thread?
Да. Или через его обертку BackgroundWorker.
1
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21
23.12.2011, 11:37  [ТС]
Ну данные функции я знаю) В общем я разобрался, косякнул в одном месте и завис в непонятках. Щас все хорошо работает. Вот вопрос возник можно или организовать прослушку двух портов? Одна программа один порт слухает, а вторая-другой.
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
23.12.2011, 13:01
В чем проблема? Создаешь два сокета с разными значениями портов и слушаешь. Их можно создавать на обычной винде, кажись, до 65к (65тыс.) штук.
0
42 / 36 / 2
Регистрация: 18.12.2011
Сообщений: 113
23.12.2011, 13:59
...
Я вроде бы все уже написал.
Прочитайте мои коментарии к коду.

Цитата Сообщение от iTheSaboteur Посмотреть сообщение
создаешь поток бесконечно слушающий какой-нибудь порт, в котором при подключении сразу вызываешь функцию обработчик-узла, которая делает еще один поток в котором принимает данные с подключенного пк. Ну и отправляет ответ.
......
РесайвФром получает данные и записывает конечную точку на машине эти данные передавшей по ссылке переданной в аргументе (да, я чуть опечатался не out а ref), используя эту точку вы можете получать нужные данные.
Это ты делаешь в одном потоке, для каждого подключившегося узла создаешь новый поток, который будет его обрабатывать - принимать данные, т.е., как обычно делаю я, (возможно это далеко не лучший вариант, спорить не буду), код недоработанный, чуть позже займусь, а пока несколько коротких вырезок:
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
public Socket listener;
public int Port = 12500;
//-----
        public event _OnConnect OnConnect;
        public event _OnDisconnect OnDisconnect;
        public event _OnReceive OnReceive;
        //-----
        public delegate void _OnConnect(ConnectArgs args);
        public delegate void _OnDisconnect(DisconnectArgs args);
        public delegate void _OnReceive(ReceiveArgs args);
        //-----
public class NetWrapper
{
public NetWrapper(IPEndPoint ListenPoint)
        {
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            listener.Bind(ListenPoint);
            Accept();
        }
}
public void Accept(){
new Thread(() =>
            {
                while(true){
                EndPoint node = new IPEndPoint(0, 0);
                byte[] data = new byte[0];
                listener.ReceiveFrom(data, ref node);
                
                    Connect((IPEndPoint)node);
                
                }
 
            }).Start();
}
public Socket Connect(IPEndPoint ConnectPoint)
        {
            int port = ++Port;
            Socket handler = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            handler.Bind(new IPEndPoint(0, port));
            handler.Connect(ConnectPoint);
            OnConnect(new ConnectArgs(node));
           //точно не помню, вроде бы после бинда в пакетах отсылается новый прослушиваемый порт.. ну да сам разберешься
            HandleNode(handler);
            return handler;
        }
private void HandleNode(Socket handler)
        {
            new Thread(() =>
            {
                byte[] data = new byte[512];
                
            HandleNode:
                int received = handler.Receive(data);
                if(received>0)
                    OnReceive(new ReceiveArgs(data, handler.RemoteEndPoint));
                if (handler.Connected)
                    goto HandleNode;
                OnDisconnect(new DisconnectArgs(handler.RemoteEndPoint));
            }).Start();
        }
/// <summary>
        /// Data sending.
        /// WARNING!
        /// If ConnectionPoint will not listen on remote machine, this method cause exception
        /// </summary>
        /// <param name="Data">Data, which need send to remote machine</param>
        /// <param name="ConnectPoint">Point(IP and PORT) on remote machine</param>
        public void Send(byte[] Data, IPEndPoint ConnectPoint)
        {
            Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            sender.Connect(ConnectPoint);
            sender.Send(Data);
        }
 
//----------------------
    /// <summary>
    /// On connect arguments
    /// </summary>
    public class ConnectArgs : EventArgs                   
    {   
                                           
        private IPEndPoint node;                           
        private DateTime date;
 
        /// <summary>
        /// Connected node
        /// </summary>
        public IPEndPoint Node { get { return node; } }
        /// <summary>
        /// Connection date 
        /// </summary>
        public DateTime Date{ get { return date; } }
        
        public ConnectArgs(EndPoint NODE)
        {
            node = (IPEndPoint)NODE;                       
            date = DateTime.Now;                           
        }                                                  
    }                                                      
    
 
    /// <summary>
    /// On Receive arguments
    /// </summary>
    public class ReceiveArgs : EventArgs
    {
        private IPEndPoint sender;
        private DateTime date;
        private byte[] data;
        /// <summary>
        /// Point, from which receives data
        /// </summary>
        public IPEndPoint Sender { get { return sender; } }
        /// <summary>
        /// Receive date
        /// </summary>
        public DateTime Date { get { return date; } }
        /// <summary>
        /// Buffer
        /// </summary>
        public byte[] Data { get { return data; } }
        public ReceiveArgs(byte[] DATA, EndPoint SENDER)
        {
            date = DateTime.Now;
            sender = (IPEndPoint)SENDER;
            data = DATA;
        }
    }
    /// <summary>
    /// On disconnect arguments
    /// </summary>
    public class DisconnectArgs : EventArgs
    {
        private IPEndPoint node;
        private DateTime date;
        /// <summary>
        /// Disconnected node
        /// </summary>
        public IPEndPoint Node { get { return node; } }
        /// <summary>
        /// Disconnect date
        /// </summary>
        public DateTime Date { get { return date; } }
        public DisconnectArgs(EndPoint NODE)
        {
            node = (IPEndPoint)NODE;
            date = DateTime.Now;
        }
    }
p.s. Что бы обрабатывать входящий трафик, нужно прибавить ЕвентХэндлер событию OnReceive;
При коннекте/отключении клиента OnConnect OnDisconnect соответственно.
p.p.s часть кода стер, за его ненадобностью
p.p.p.s Как вы наверное поняли, сокет сам слушает заданный вами порт, и автоматически принимает подключения и получает данные, вызывая событие ОнРесайв. Все это творится в отдельном потоке, отправка данных осуществляется функцией Send(byte[], EndPoint);
2
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21
26.12.2011, 05:43  [ТС]
iTheSaboteur, body90, спасибо вам. Сделал. Всё работает
0
 Аватар для body90
467 / 344 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
26.12.2011, 06:15
Пожалуйста! Luck999, выложите код в тему. Кому нибудь, возможно, еще пригодится.
0
3 / 3 / 2
Регистрация: 16.12.2011
Сообщений: 21
26.12.2011, 07:54  [ТС]
Лучший ответ Сообщение было отмечено как решение

Решение

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
//часть программы№2 находится в режим прослушке
private void ServStart() // метод для старта сервера
        {
 
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 17103);
            Socket ClientSock; // сокет для обмена данными.
            Listener = new TcpListener(ipep);
            Listener.Start();//запуск прослушки
            Int32 i = 0;    
             byte[] buf = new byte[2]; //для отсылки ответов. хотя можно и др вариантами
            // начали слушать
            while (true) 
            {
                try
                {   
                    ClientSock = Listener.AcceptSocket(); // принимаем пакет                    
                    i = 0;
                     while (ClientSock.Connected)
                    {              
                       try
                       {
                           i = ClientSock.Receive(buffer);             // попытка чтения   
                           //buf-записали в него чегонить
                          ClientSock.Send(buf);
                          ClientSock.Close();                   
                         }
                        catch
                        {
                            ClientSock.Close();                          // ну эт если какая хрень..
                        }
                    }
                }
                catch
                {
                }
            } 
        }
 
 
//часть программы№1 по нажатию кнопки отправляет данные по сокетам и получает ответ от программы№2
 
 private void button6_Click(object sender, EventArgs e)
        {
            byte[] buffer=new byte[2];
            //создаём соккет для отправки запроса серверу
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 17103);
           //  buffer-записали в негочегонить
            try
            {
                //создаём соединение
                sock.Connect(ipep);
                if (sock.Connected)
                {
                    //отправляем запрос на сервер
                    sock.Send(buffer);
                    int i = sock.Receive(buf);
                    sock.Close();
                }
            }
            catch
            {
                sock.Close();
            }
        }

Как-то так. Бегло пробежался вроде ошибок нет, просто в моем рабочем коде много лишнего. Что явно не по теме будет. Так же делал с прослушкой на двух портах разными программами, но так как делал в качестве проверки работает или нет, уже стер. При необходимости могу написать
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.12.2011, 07:54
Помогаю со студенческими работами здесь

Windows sockets приложения с сокетами, написание приложения сервер-клиент
Написать программу-сервер и программу - клиент. Клиент читает файл, пересылает его серверу. Сервер, в свою очередь, пересылает файл всем...

Работа с сокетами - скачать на сервер информацию от клиента
взаимодействие сервера и клиента работает на ура :) вопрос возник когда я захотел сделать взаимодействие сервера с несколькими клиентами....

Работа с сокетами Беркли: Нужно, чтобы сервер выдавал степень числа
Привет всем! Кто может помочь (объяснить) с написанием кода по сокетам беркли? Мне нужно, чтобы сервер выдавал степень числа. Не нужно...

Авторизация в программе (клиент-сервер)
Добрый день! Пишу на Delphi 7, суть такова: Авторизация в программе - пользователь вводит в клиентской части логин и пароль, эти данные...

Клиент и сервер Lotus на одной машине!
Есть необходимость установить связку Сервер+клиент Лотуса на одной несетевой машине (домашний компьютер). Необходимость эта возникла для...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru