Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/29: Рейтинг темы: голосов - 29, средняя оценка - 4.90
Java, C# - Expert
 Аватар для IceSqueez
69 / 69 / 12
Регистрация: 09.08.2011
Сообщений: 284

Передача сообщения от клиентов к серверу Socket

17.03.2013, 11:35. Показов 6089. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, сидел целые 2 сутки думал разберусь сам... но не тут то было... Суть проблемы:
Надо написать службу которая через Socket будет ловить SQL запросы и взаимодействовать с базой, саму реализацию взаимодействия я сделал, все работает корректно, но тут я перешел к Socketу и все... понеслась, не могу сделать передачу сообщения и все, почти все смог сделать, и присоединение клиента и отсоединение (отлавливание этих моментов и вывод сообщений), но вот саму передачу сделать не могу, вот мой код, скажите что тут надо сделать, что-бы ловилось сообщение и писалось в richTextBox1

Класс Listener.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
using System;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
 
namespace Server
{
    internal class Listener
    {
        private Socket s;
 
        public bool Listening { get; private set; }
 
        public int Port { get; private set; }
 
        public Listener(int port)
        {
            Port = port;
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
 
        public void Start()
        {
            if (Listening)
                return;
 
            s.Bind(new IPEndPoint(0, Port));
            s.Listen(0);
 
            s.BeginAccept(CallBack, null);
 
            Listening = true;
        }
 
        public void Stop()
        {
            if (!Listening)
                return;
            s.Close();
            s.Dispose();
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
 
        public void CallBack(IAsyncResult ar)
        {
            try
            {
                var socket = s.EndAccept(ar);
                if (SocketAccepted != null)
                {
                    SocketAccepted(socket);
                }
                s.BeginAccept(CallBack, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }
 
        public delegate void SocketAcceptedHandler(Socket e);
 
        public event SocketAcceptedHandler SocketAccepted;
    }
}
Server.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
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Windows.Forms;
 
namespace Server
{
    public partial class Form1 : Form
    {
        private static Listener l;
        private static List<Socket> sockets;
        public Form1()
        {
            InitializeComponent();
            l = new Listener(5003);
            sockets = new List<Socket>();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            l.SocketAccepted += l_SocketAccepted;
            l.Start();
        }
 
        void l_SocketAccepted(Socket e)
        {
            richTextBox1.Text = string.Format("New connection: {0}\n{1}\n==============", e.RemoteEndPoint, DateTime.Now);//кстати тут выбивает попытку доступа к объекту из потока в котором он не был создан.
            sockets.Add(e);
        }
    }
}
Client.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
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
 
namespace Client
{
    public partial class Form1 : Form
    {
        private Socket s;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s.Connect("127.0.0.1", 5003);
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            var text = Encoding.ASCII.GetBytes(textBox1.Text);
            s.Send(text);
        }
    }
}

Заранее спасибо.

Добавлено через 7 часов 18 минут
Тема все еще актуальна...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.03.2013, 11:35
Ответы с готовыми решениями:

Несколько клиентов к одному серверу через Socket
У меня не получается подключить больше одного клиента к одному серверу. Для тестирования использую корпоративную сеть. Хочу просто...

Как серверу выборочно посылать сообщения одному из клиентов?
сервер // Get port from player // scanf(&quot;%5d&quot;, &amp;port); // Create a new socket to listen for client connections if...

ServerSocket передача файлов от клиентов серверу
Нужна помощь! Есть приложение для win. Сервер - клиент для передачи файлов. Работает это все дело на компонентах serversocket и...

10
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
17.03.2013, 17:32
Цитата Сообщение от IceSqueez Посмотреть сообщение
//кстати тут выбивает попытку доступа к объекту из потока в котором он не был создан.
SocketAccepted вызывается в CallBack, который в свою очередь работает в отдельном (асинхронном) потоке. Обычно в такое ситуации используют Invoke (Вызов функции в исходном потоке, посмотрите более детально в интернете).

C#
1
2
3
4
5
6
7
8
9
10
void l_SocketAccepted(Socket e)
        {
            richTextBox1.Invoke(new Action(delegate
            {
                richTextBox1.Text = string.Format("New connection: {0}\n{1}\n==============",
                    e.RemoteEndPoint, DateTime.Now);
            }));
            //кстати тут выбивает попытку доступа к объекту из потока в котором он не был создан.
            sockets.Add(e);
        }
Выводить сообщение об ошибке непосредственно в классе - очень плохая идея. Лучше просто закрывать соединение и генерировать событие об ошибке. Я вот про этот участок кода.
C#
1
2
3
4
catch (Exception ex)
{
  MessageBox.Show("Error: " + ex.Message);
}
Где метод принимающий данные на сервер? Или в чем проблема?
1
Java, C# - Expert
 Аватар для IceSqueez
69 / 69 / 12
Регистрация: 09.08.2011
Сообщений: 284
17.03.2013, 19:03  [ТС]
С этим я уже разобрался, но я не знаю как сделать приём данных на сервере... что и где написать что-бы был метод типа: "Я принял текст что с ним делать ?", что-бы я в этом методе мог генерировать SQL запрос и отправить его к базе (это я знаю как сделать мне надо сам метод для приёма текста).

Уже не знаю что делать... голова кругом идет..)) через пару дней сдача курсовой, а я не могу в Sockete разобраться...
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
17.03.2013, 19:28
Цитата Сообщение от IceSqueez Посмотреть сообщение
но я не знаю как сделать приём данных на сервере...
Метод recive вам в помощь.

Дабы особо не трындеть, вот библиотека, для передачи данных (корявая немного, но рабочая 100%). Всё что нужно - два соединенных сокета (вы уже это сделали) и создать свой класс-обертку, для данных сообщения, что-то на подобие такого:

C#
1
2
3
4
5
6
7
8
9
10
11
[Serializable]
public class MyMessage : Message
{
private string _sqlCommandString;
 
public MyMessage(string str)
{sqlCommandString = str;}
 
public string SqlCommandString 
{ get {return this.sqlCommandString: }}
 }
Далее всё очень просто - на клинте отправляем через public void Send(Message message) наше сообщение. На сервере делаем подписку на public event EventHandler<MessageEventArgs> getMessage; и обрабатываем все полученные сообщения (имейте ввиду, что обработка будет выполнятся в отдельном потоке, ибо используется асинхронный метод приема сообщений). И что хорошо - работает в обоих направлениях.
Вложения
Тип файла: zip NekoChat.NetworkManager.zip (44.2 Кб, 38 просмотров)
1
45 / 45 / 9
Регистрация: 19.11.2012
Сообщений: 124
17.03.2013, 19:34
Ну во 1-х, по поводу строки
C#
1
s.Listen(0);
метода Start. Меня смущает этот 0. Или у вас приложение не многоклиентское?
И в строке
C#
1
s.Bind(new IPEndPoint(0, Port));
меня так же смущает 0 на месте IP адреса.

Во 2-х, просто посылать сообщение методом Send (если это некая текстовая строка) не самая лучшая идея, нужно проверять все ли данные отправились, то есть написать свою функцию отправки, которая будет выглядеть примерно так: (пишу свою ф-кцию и на особую политкорректность не претендую):

C#
1
2
3
4
5
6
7
    static void sendMessage(Socket s, string message)
    {
        int messageLength = -1;
        byte[] msgToSent = Encoding.UTF8.GetBytes(message);
        while (messageLength != msgToSent.Length)
            messageLength = s.Send(msgToSent, 0, msgToSent.Length, SocketFlags.None);
    }
Проблема в этой функции может возникнуть тогда, когда данные не могут передаться, то есть получим зависание программы, но никто не мешает вам её доработать =)

В 3-х, при приеме сообщения, всяческие проверки тоже не будут лишними (пишу так же свою ф-кцию, возможно она кривая, но вполне работает):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static string receiveMessage(Socket s)
    {
        if (s.Poll(1000000, SelectMode.SelectRead) == false)
            return "ERROR";
        string result = "";
        while (result == "" || result == " ")
        {
            int buffCnt = s.Available;
            int recCnt = 0;
            byte[] msg = new byte[buffCnt];
            while (recCnt != buffCnt)
                recCnt = s.Receive(msg, 0, buffCnt, SocketFlags.None);
            result = "";
            result = Encoding.UTF8.GetString(msg);
        }
        return result;
    }
1
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
17.03.2013, 19:44
fictiont, в точку! Я когда писал чат, у меня было около дюжины разнотипных сообщений, причем их длина колебалась от 10байт, до 10Кбайт. А учитывая, что сервер был многоклиентский, отправлять "по частям вызывая десять раз метод Send" нельзя. Именно из-за этого мне пришлось написать общую обертку для сообщений и нахимичить класс для отправки/приема сообщений.
1
Java, C# - Expert
 Аватар для IceSqueez
69 / 69 / 12
Регистрация: 09.08.2011
Сообщений: 284
17.03.2013, 20:28  [ТС]
Спасибо ребята, очень помогли, только у меня вопрос возник:
C#
1
s.Listen(0);
а что тут не так ??


C#
1
s.Bind(new IPEndPoint(0, Port));
А это я написал просто для теста (ибо тестирую на локалхосте)
на данный момент это уже переписано на сопоставление IP клиента (локального).
0
45 / 45 / 9
Регистрация: 19.11.2012
Сообщений: 124
17.03.2013, 20:36
Цитата Сообщение от IceSqueez Посмотреть сообщение
Спасибо ребята, очень помогли, только у меня вопрос возник:
C#
1
s.Listen(0);
а что тут не так ??
Мм.. просто что здесь будет при подключении более чем одного клиента?
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
17.03.2013, 20:46
Цитата Сообщение от fictiont Посмотреть сообщение
Мм.. просто что здесь будет при подключении более чем одного клиента?
если последовательно, то ровным счетом ничего. и если мне не изменяет память, то ноль означает что нет ограничений на очередь.
1
45 / 45 / 9
Регистрация: 19.11.2012
Сообщений: 124
17.03.2013, 20:48
Цитата Сообщение от Wolfdp Посмотреть сообщение
если последовательно, то ровным счетом ничего. и если мне не изменяет память, то ноль означает что нет ограничений на очередь.

Ок, просто не был уверен в нуле. Было предположение, что он не пускает никого в очередь.
Последовательно не считается. =)
0
Java, C# - Expert
 Аватар для IceSqueez
69 / 69 / 12
Регистрация: 09.08.2011
Сообщений: 284
18.03.2013, 19:49  [ТС]
Так все вроде-бы получается... осталась одна проблема, не могу установить службу моего проекта захожу в VS 2012 Promt и пишу:

C:\Program Files (x86)\Microsoft Visual Studio 11.0>installUtil.exe /i MachineEm
ulator
(MachineEmulator) это название проекта со службой.
на что мне отвечают:

C:\Program Files (x86)\Microsoft Visual Studio 11.0>installUtil.exe /i С:\MachineEm
ulator
Microsoft (R) .NET Framework Installation utility, версия 4.0.30319.17929
(c) Корпорация Майкрософт (Microsoft Corp.). Все права защищены.

Возникло исключение при инициализации установки:
System.IO.FileNotFoundException: Невозможно загрузить файл или сборку "file:///C
:\MachineEmulator" или один из
зависимых от них компонентов. Не удается найти указанный файл..

перепробывал все что можна, и к самой службе (bin\debug\MachineEmulator.exe), и к проекту и к солюшину, всегда тот-же ответ, какой путь там надо прописывать ?)))))

Добавлено через 22 часа 23 минуты
На правах "Up'а"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.03.2013, 19:49
Помогаю со студенческими работами здесь

Передача сообщения серверу
Добрый день форумчане! Имеется модуль WiFi(ESP8266) с поднятым на нем TCP сервером. Но ноуте имеется клиент на C#. Клиент постоянно...

Передача сообщения от клиента к серверу, сокеты
Хочу передать сообщение от клиента к серверу и вывести это сообщение. Как это сделать? сервер #ifndef UNICODE #define UNICODE ...

Socket несколько клиентов
Здравствуйте! Пишу прогу состоящую из двух серверов, смысл которой принять инфу от клиента на один сервер и передать её клиентам...

Socket авторизация клиентов (Нужен совет)
Интересует где лучше хранить логин и пароль а так же доп инфу о пользователе на сервере, что бы проходить авторизацию? Первая идея...

Алгоритм обработки клиентов сервером (Socket)
Здравствуйте, друзья. Я всю голову сломал над тем, как правильно устроить общение клиента с сервером. Как вообще работает сервер? Вот...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru