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

Передача значений переменных через сокет

16.04.2012, 19:18. Показов 10690. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый всем вечер. Вопрос: имеется клиент, он должен передать серверу 4 переменных. Сервер должен распознать эти 4 переменных отдельно, т.е не единым массивом, а как 4 переменные. Как это добиться?
Максимум, что у меня получалось нормально принять - это раздельных 2 переменных, если больше то они склеивались с остальными.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 {//клиент
                IPHostEntry ipHost = Dns.Resolve(ipadr);
                IPAddress ipAddr = ipHost.AddressList[0];
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 1111);
                Socket send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                send.Connect(ipEndPoint);
                listBox1.Items.Add("Socket connected to" + send.RemoteEndPoint.ToString());
                string n = "3";     //переменные которые нужно передать
                string lambda = "4,8";
                string mu = "2";
                string nt = "1000";
 
                byte[] msg = Encoding.ASCII.GetBytes(n+lambda+mu+nt);
                int bytesSent = send.Send(msg);
                send.Shutdown(SocketShutdown.Both);
                send.Close();
            }
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
//Сервер
 {
            string n1=null;
            string lambda1 = null;
            string mu1 = null;
            string nt1 = null;
            string ipadr;
            Console.WriteLine("Введите IP адрес");
            ipadr = Console.ReadLine();
            IPHostEntry ipHost = Dns.Resolve(ipadr);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 1111);
            Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                sListener.Bind(ipEndPoint);
                sListener.Listen(10);
                while (true)
                {
                    Console.WriteLine("Waiting for a connection on port {0}", ipEndPoint);
                    Socket handler = sListener.Accept();
                    string data = null;
                    while (true)
                    {
                        byte[] bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
                        data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                        if (data.IndexOf("") > -1)
                        {
                       break;
                        }
                    }
                    Console.WriteLine("Text Received:   {0}", data);
                    n1 = data;
                    Console.WriteLine("N:   {0}", n1);
                    string theReply = "Thank you for those  " + data.Length.ToString() + "characters . . .";
                    byte[] msg = Encoding.ASCII.GetBytes(theReply);
                    handler.Send(msg);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                    break;
                }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.04.2012, 19:18
Ответы с готовыми решениями:

Передача значений переменных или ссылок, неконтролируемое изменение переменных
// заголовок класса ObservableCollection<LineDom> Method1; Method1 = new...

Передача файла через сокет
Итак... у меня сложилась одна затруднительная ситуация. Есть сервер, есть клиент. С передает К файл...

Неккоректная передача значений глобальных переменных
Здравствуйте. При вызове функции передаю ей некоторые элементы глобального массива...

Передача значений переменных через URL
Здравствуйте! В PHP новичок совсем, но кое-как понял, что можно передавать значения переменных...

20
98 / 98 / 46
Регистрация: 21.03.2012
Сообщений: 378
17.04.2012, 00:10 2
Зачем на сервере 2 бесконечных цикла?
я выложу геморный пример, так как по другому не знаю
там использую "спец символ" для опознания текста, твоя строки (string n = "3"; //переменные которые нужно передать string lambda = "4,8"; string mu = "2"; string nt = "1000"; ) собираем в одну строку n и разделяем спец символом string n = "3;4,8;2;1000;"; данным спец символом является ";", ну и отправляем на сервер, там разбираем строку

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//клиент
            string ipadr = "127.0.0.0";
            IPHostEntry ipHost = Dns.Resolve(ipadr);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 1111);
            Socket send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            send.Connect(ipEndPoint);
            Console.WriteLine("Socket connected to" + send.RemoteEndPoint.ToString());
            string n = "3;4,8;2;1000;";     //переменные которые нужно передать
 
            byte[] msg = Encoding.ASCII.GetBytes(n);
            int bytesSent = send.Send(msg);
            send.Shutdown(SocketShutdown.Both);
            send.Close();
            Console.ReadKey();
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
//сервер
            string[] n1 = new string[5];
            string ipadr = "127.0.0.0";
            IPHostEntry ipHost = Dns.Resolve(ipadr);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 1111);
            Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                sListener.Bind(ipEndPoint);
                sListener.Listen(10);
                while (true)
                {
                    Console.WriteLine("Waiting for a connection on port {0}", ipEndPoint);
                    Socket handler = sListener.Accept();
                    string data = "";
                    try
                    {
                        byte[] bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
                        data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
                        int l = 0;
                        int k = 0;
                        int p = 0;
                        for (int i = 0; i < data.Length; i++)
                        {
                            if (data[i] != ';')
                            {
                                k = k + 1;
                            }
                            else
                            {
                                for (int j = l; j < k; j++)
                                {
                                    n1[p] = n1[p] + data[j];
                                }
                                l = k + 1;
                                k = k + 1;
                                p = p + 1;
                            }
                        }
                        int n = 0;
                        while (n1[n] != null)
                        {
                            Console.WriteLine(n1[n]);
                            n = n + 1;
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                    Console.WriteLine("Text Received:   {0}", data);
                    string theReply = "Thank you for those  " + data.Length.ToString() + "characters . . .";
                    byte[] msg = Encoding.ASCII.GetBytes(theReply);
                    handler.Send(msg);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                    Console.ReadKey();
                    break;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
ну или использую сериализацию/десериализацию сделать...
2
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
17.11.2012, 17:03 3
Всем привет.Новую тему решил не создавать - задам вопрос тут.
Почему вешает приложение?
C#
1
 Socket con = s.Accept();
Полный код.
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
       public void handler()
        {
            while(!isStoped)
            {
                try
                {
                    Socket con = s.Accept();
                    lg("Клиент подключен!");
                    while (true)
                    {
                       
                        byte[] msg = new byte[con.Available];
                        con.Receive(msg);
                        string str = Encoding.UTF8.GetString(msg);
                        if (str == "exit") break;
                        lg(str);
                        
                    }
                    con.Close();
                }
                catch (Exception ex)
                {
                    lg(ex.ToString());
                }
            }
        }
0
Эксперт .NET
17689 / 12874 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
17.11.2012, 19:04 4
Привет.

Цитата Сообщение от Athlon_33_88 Посмотреть сообщение
Почему вешает приложение?
Потому что метод Accept блокирует текущий поток до тех пор, пока клиент не подключится.
Чтобы не вешался основной поток, запускайте метод handler в отдельном.
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
18.11.2012, 05:52 5
Fourd, зачем всё так усложнять? В .net всё уже придумано до нас

Добавлено через 31 минуту
Клиент (отправляем строки):
C#
1
2
3
4
5
6
7
8
9
10
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect("localhost", 11111);
NetworkStream nws = new NetworkStream(s);
BinaryWriter bw = new BinaryWriter(nws);
string s = "Привет!";
bw.Write(s); //Так можно отправлять переменную любого стандартного типа или даже
                  //весь огромный класс, серилизировав его.
bw.Write("Как дела?");
bw.Write(123)
// ...
Сервер (получаем строки):
C#
1
2
3
4
5
6
7
8
9
10
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket s_ = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s_.Bind(new IPEndPoint(IPAddress.Any, 11111));
s_.Listen(1);
s = s_.Accept();
NetworkStream nws = new NetworkStream(s);
BinaryReader br = new BinaryReader(nws);
string s1 = br.ReadString(); //"Привет!"
string s2 = br.ReadString(); //"Как дела?"
int num = br.ReadInt32(); //123
В общем, посмотрите с какими типами умеют работать классы BinaryWriter и BinaryReader.

Добавлено через 4 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
Чтобы не вешался основной поток, запускайте метод handler в отдельном.
Или используйте асинхронный вариант.
2
Fourd
20.11.2012, 18:02
  #6

Не по теме:

body90, не знаю на тот момент показалось что так будет проще, так как сам только учил, для задачи дипломки :)) да и честно говоря, всю причину не припомню...

0
98 / 81 / 16
Регистрация: 14.01.2011
Сообщений: 438
21.11.2012, 10:08 7
Fourd, у spprog первый цикл для принятия клиентов,второй - "бесконечный" для полного считывания сообщения - завершается по окончанию его(сообщения). А так у автора была просто конкатенация строк,поэтому не удавалось нормально передать. Можно через пробелы передавать,и на сервере парсить.
1
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
21.11.2012, 15:52 8
Цитата Сообщение от NowMatrix Посмотреть сообщение
Можно через пробелы передавать,и на сервере парсить.
Ну да, а если в строке будет пробел? Что делать? Разделителями пользоваться - не лучшая практика.
Тут 2 варианта:
1) отправлять сначала длину строки, а потом саму строку;
2) отправлять/получать с помощью BinaryWriter/BinaryReader (он сам использует первый способ), как я показал выше.

Думаю, понятно, что 2-й вариант поудобшее.
1
98 / 81 / 16
Регистрация: 14.01.2011
Сообщений: 438
21.11.2012, 19:05 9
body90, да,конечно ваш вариант намного удобнее. Просто и с самими сокетами(напрямую) тоже надо поиграться хоть раз ).
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
22.11.2012, 01:43 10
Цитата Сообщение от NowMatrix Посмотреть сообщение
Просто и с самими сокетами(напрямую) тоже надо поиграться хоть раз )
Согласен. Ну тогда один вариант... Сначала отправлять, например, 1 байт с числом, означающим длину передаваемой строки, а потом передавать эту строку.
0
98 / 81 / 16
Регистрация: 14.01.2011
Сообщений: 438
22.11.2012, 18:40 11
Цитата Сообщение от body90 Посмотреть сообщение
Согласен. Ну тогда один вариант... Сначала отправлять, например, 1 байт с числом, означающим длину передаваемой строки, а потом передавать эту строку.
Согласен,самое разумное решение.
0
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
02.12.2012, 22:37 12
И снова вопрос:
Сообщения на сервер приходят исправно.Вот код:
C#
1
2
3
4
5
6
7
8
9
                    while (true)
                    {
                        Socket con = s.Accept();
                        byte[] msg = new byte[con.Available];
                        con.Receive(msg);
                        string str = Encoding.UTF8.GetString(msg);
                        lg(str); //break;
                        con.Close();
                    }
Вопрос: можно ли (если можно, то как) внутри данного вайла отправить ответ клиенту который прислал сообщение?
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
04.12.2012, 12:23 13
C#
1
con.Send(msg);
1
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
23.12.2012, 15:05 14
Цитата Сообщение от body90 Посмотреть сообщение
con.Send(msg);
Разобрался, но это сообщение не получает клиент, подскажите что не так:

C#
1
2
3
4
5
6
7
8
9
10
 if(!s.Connected)s.Connect(endPoint);//подключаемся к серверу
  byte[] msg = Encoding.UTF8.GetBytes(mtd.ToString()); //Конвертируем номер метода
   s.Send(msg);//отправляем номер метода на сервер
    //Socket otvet = s.Accept(); - тут выдается исключение, что нужно сделать s.Listen();
 
// Тут предпологается поймать ответ от сервера, который успешно отправляется
    byte[] otvet_msg = new byte[s.Available];
    s.Receive(otvet_msg);
    string otv_port = Encoding.UTF8.GetString(otvet_msg);
    if (s.Connected) s.Close();
Добавлено через 23 часа 21 минуту
Вопрос еще актуален....
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
23.12.2012, 20:06 15
Народ жаждет больше кода!
В общем, покажите полностью как вы создавали объекты s, endPoint, ...
0
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
23.12.2012, 20:14 16
переменные ip и port парсятся из текстбоксов главной формы
mtd - int'овое число,task - строка, которую нужно потом передать.
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
    class MainServer
    {
        public delegate void logDelegate(string s);
        public static logDelegate lg;
        public IPAddress ip;
        public int port;
        public int myPort;
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endPoint;
        public void Start(int mtd,string task)
        {
            endPoint = new IPEndPoint(ip, port);
            try
            {
                
                if(!s.Connected)s.Connect(endPoint);
                byte[] msg = Encoding.UTF8.GetBytes(mtd.ToString()); 
                s.Send(msg);
                //Socket otvet = s.Accept();//выдает исключение
                
                byte[] otvet_msg = new byte[s.Available];
                s.Receive(otvet_msg);
                string otv_port = Encoding.UTF8.GetString(otvet_msg);
                //закрываем текущие сокеты
                lg(otv_port);/
                if (s.Connected) s.Close();
            }
            catch (Exception ex)
            { lg(ex.ToString()); }
        }
 
    }
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
23.12.2012, 23:11 17
А код на другой стороне сокета можно увидеть?
0
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
23.12.2012, 23:19 18
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
  public class MainServ
    {
        //Делегат для обратной связи с главной формой
         public delegate void logDelegate(string s);
         public static logDelegate lg;
        //==============================
       
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endPoint;
        int amount = 10;//колчество клиентов
        public int mainPort = 1906, port1=0, port2=0, port3=0;//значения портов
        
        //Основной конструктор
        public MainServ()
        {
            endPoint = new IPEndPoint(IPAddress.Any, 1906);
        }
 
        //Консрутор сервера для определенного порта
        public MainServ(int port)
        {
            endPoint = new IPEndPoint(IPAddress.Any, port);
            mainPort = 1906;
        }
 
        //Запуск сервера
        public void Start()
        {
            try
            {
                s.Bind(endPoint);
                s.Listen(amount);
                lg("Ожидаем подключения...");
            }
            catch (Exception ex)
            {
                lg("Произошла ошибка:\n" + ex.ToString());
            }
            while (true)
            {
                try
                {
 
                    while (true)
                    {
                        Socket con = s.Accept();
                        byte[] msg = new byte[con.Available];
                        con.Receive(msg);
                        string str = Encoding.UTF8.GetString(msg);
                        lg(str); //break;
                        byte[] m = Encoding.UTF8.GetBytes("1906"); //Конвертируем номер метода
                        con.Send(m);
                        lg("Sendig:"+m);
                        con.Close();
                    }
 
                }
                catch (Exception ex)
                {
                    lg(ex.ToString());
                }
            }
        }
}
0
464 / 341 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
24.12.2012, 10:31 19
Цитата Сообщение от Athlon_33_88 Посмотреть сообщение
port1=0, port2=0, port3=0
Использовать порты ниже 1024 не феншуйно.

А вы точно выставляете одинаковые порты на сервере и клиенте? Запускаете оба приложения на одном компьютере? В трассировщике смотрели происходит ли коннект?
0
(x(x_(x_x(О_о)x_x)_x)x)
64 / 56 / 6
Регистрация: 04.09.2010
Сообщений: 301
24.12.2012, 12:09 20
клиент нормально коннектится к серверу и присылает ему сообщение после чего сервер удачно выводит его в поле лога,потом по Вашей рекомендации я отправляю ответ клиенту методом Send,который уходит нормально, но клиент его не получает.склоняюсь к тому, что я пропустил важную строчку,которая позволяет клиенту поймать поток байт...

Добавлено через 38 минут
P.S.
Цитата Сообщение от body90 Посмотреть сообщение
port1=0, port2=0, port3=0
Пока вообще не используются, будут использоваться потом, сейчас главное добиться передачи сообщений в обе стороны
0
24.12.2012, 12:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.12.2012, 12:09
Помогаю со студенческими работами здесь

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

Передача hbitmap через сокет
У меня есть часть программы которая делает скриншот экрана в hbitmap и мне нужно отправить этот...

Передача массива через сокет
Здравствуйте. Подскажите пожалуйста как можно передать большой массив(4К-64К) целочисленных...

Передача массива через сокет
здравствуйте. пытался сделать так. на клиенте: try { Socket s = new Socket(&quot;192.168.0.1&quot;,...


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

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