Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > TCPClient / TCPListener проблема с русским языком


Автор: ziga 13.5.2010, 15:44
Взял пример из MSDN 

TCPClient
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            string test;
            Console.Write("test: ");
            test = Console.ReadLine();

            Connect("127.0.0.1", test);
        }

        static void Connect(String server, String message)
        {
            try
            {
                // Create a TcpClient.
                // Note, for this client to work you need to have a TcpServer 
                // connected to the same address as specified by the server, port
                // combination.
                Int32 port = 13000;
                TcpClient client = new TcpClient(server, port);

                // Translate the passed message into ASCII and store it as a Byte array.
                Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);

                // Get a client stream for reading and writing.
                //  Stream stream = client.GetStream();

                NetworkStream stream = client.GetStream();

                // Send the message to the connected TcpServer. 
                stream.Write(data, 0, data.Length);

                Console.WriteLine("Sent: {0}", message);

                // Receive the TcpServer.response.

                // Buffer to store the response bytes.
                data = new Byte[256];

                // String to store the response ASCII representation.
                String responseData = String.Empty;

                // Read the first batch of the TcpServer response bytes.
                Int32 bytes = stream.Read(data, 0, data.Length);
                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                Console.WriteLine("Received: {0}", responseData);

                // Close everything.
                stream.Close();
                client.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }

            Console.WriteLine("\n Press Enter to continue...");
            Console.Read();
        }
    }
}



TCPListener

Код

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TcpListener1
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener server=null;   
            try
            {
              // Set the TcpListener on port 13000.
              Int32 port = 13000;
              IPAddress localAddr = IPAddress.Parse("127.0.0.1");
              
              // TcpListener server = new TcpListener(port);
              server = new TcpListener(localAddr, port);

              // Start listening for client requests.
              server.Start();
                 
              // Buffer for reading data
              Byte[] bytes = new Byte[256];
              String data = null;

              // Enter the listening loop.
              while(true) 
              {
                Console.Write("Waiting for a connection... ");
                
                // Perform a blocking call to accept requests.
                // You could also user server.AcceptSocket() here.
                TcpClient client = server.AcceptTcpClient();            
                Console.WriteLine("Connected!");

                data = null;

                // Get a stream object for reading and writing
                NetworkStream stream = client.GetStream();

                int i;

                // Loop to receive all the data sent by the client.
                while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
                {   
                  // Translate data bytes to a ASCII string.
                  data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                  Console.WriteLine("Received: {0}", data);
               
                  // Process the data sent by the client.
                  data = data.ToUpper();

                  byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

                  // Send back a response.
                  stream.Write(msg, 0, msg.Length);
                  Console.WriteLine("Sent: {0}", data);            
                }
                 
                // Shutdown and end connection
                client.Close();
              }
            }
            catch(SocketException e)
            {
              Console.WriteLine("SocketException: {0}", e);
            }
            finally
            {
               // Stop listening for new clients.
               server.Stop();
            }

              
            Console.WriteLine("\nHit enter to continue...");
            Console.Read();
          }   
        }
}



возникли несколько вопросов:
  • Запускаю сервак, и клиент отправляю клиентом сообщение всё нормально возвращает. Единственная проблема то что когда отправляю текст на русском языке возвращает "???????????????" в чём проблема?
  • Как мне передать сообщение больше чем объём 250 байт (незная размера информации)
  • Можно такми способом получать таблицу из базы к примеру отправив клиентом select * from user получить ответ со списком пользователей в виде таблицы? если да то как лучше всего это сделать?



Автор: SickFxck 31.5.2010, 21:51
Цитата(ziga @  13.5.2010,  15:44 Найти цитируемый пост)
Запускаю сервак, и клиент отправляю клиентом сообщение всё нормально возвращает. Единственная проблема то что когда отправляю текст на русском языке возвращает "???????????????" в чём проблема?

Проблема в System.Text.Encoding.ASCII.GetBytes(). Можешь попробовать UTF-8.

Цитата(ziga @  13.5.2010,  15:44 Найти цитируемый пост)
Как мне передать сообщение больше чем объём 250 байт (незная размера информации)

Например, передавая сначала размер (куска или всего сообщения).

Цитата(ziga @  13.5.2010,  15:44 Найти цитируемый пост)
Можно такми способом получать таблицу из базы к примеру отправив клиентом select * from user получить ответ со списком пользователей в виде таблицы? если да то как лучше всего это сделать?

Ни в коем случае клиент не должен отправлять запрос или его часть, который будет выполняться на сервере, за исключением особых случаев. Клиент, по-хорошему, должен отправить какую-то команду, которую сервер воспримет как запрос таблицы пользователей.

Добавлено через 32 секунды
На дату не посмотрел

Автор: nmn 30.7.2010, 11:32
Цитата(SickFxck @  31.5.2010,  21:51 Найти цитируемый пост)
Ни в коем случае клиент не должен отправлять запрос или его часть, который будет выполняться на сервере, за исключением особых случаев. Клиент, по-хорошему, должен отправить какую-то команду, которую сервер воспримет как запрос таблицы пользователей.

хмм, а разве команда не считается запросом? как это увязывается с первой фразой?

Автор: neic 31.7.2010, 22:53
Цитата(SickFxck @  31.5.2010,  21:51 Найти цитируемый пост)
Цитата(ziga @  13.5.2010,  15:44 )Запускаю сервак, и клиент отправляю клиентом сообщение всё нормально возвращает. Единственная проблема то что когда отправляю текст на русском языке возвращает "???????????????" в чём проблема?Проблема в System.Text.Encoding.ASCII.GetBytes(). Можешь попробовать UTF-8.

Нужно сделать так:
Код

System.Text.Encoding.Default.GetString()

Делал на VB.NET, но думаю разницы нет.

Автор: jonie 2.8.2010, 08:24
Цитата

    * Можно такми способом получать таблицу из базы к примеру отправив клиентом select * from user получить ответ со списком пользователей в виде таблицы? если да то как лучше всего это сделать?
можно полученные результаты на сервере сериализовать например в DataSet и превратить его в XML, по которому и восстановить исходный dataset на клиенте

Автор: Gleb 2.8.2010, 09:32
Цитата(nmn @  30.7.2010,  14:32 Найти цитируемый пост)
хмм, а разве команда не считается запросом? как это увязывается с первой фразой? 

SickFxck указывал на проблемы с безопасностью и типизацией и имел в виду передачу типа отчета (например в enum, flags или специальном классе), а не sql-запроса, этот отчет генерирующего.
И я с ним полностью согласен, потому что нужно четко понимать зачем это делается и не изобретаете ли вы Management Studio.


Цитата(ziga @  13.5.2010,  18:44 Найти цитируемый пост)
Можно такми способом получать таблицу из базы к примеру отправив клиентом select * from user получить ответ со списком пользователей в виде таблицы? если да то как лучше всего это сделать?

Вы можете передавать DataSet, но имейте в виду, что вам понадобится сжатие трафика, потому что сам по себе DataSet достаточно тяжеловесен.
Я рекомендую вам использовать WCF, с ним вам хотя бы не придется изобретать свои велосипеды в плане безопасности, обработки ошибок, сжатия трафика и много другого.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)