Автор Тема: Каверзная проблема в C# при работе с сокетами  (Прочитано 2706 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Ноябрь 04, 2012, 01:05:50 am
Прочитано 2706 раз

lawliet93

  • Частный гость

  • Оффлайн
  • ***

  • 113
  • Репутация:
    -2
    • Просмотр профиля
Кукареку! kot_krut хД Такая беда, есть 2 проги. сервер и клиент, и в комплекте с ними трабла которая вот какая: Когда клиент посылает данные на серв, то серв печатает эти данные у ся в консоли, НО, 1) Текст выводиться не заново, а как бэ поверх предыдущего сообщения, например, клиент послал - Абракадабра, и в консоли сервера печатаеться это, но если дальше клиент пошлет слово которое состоит из меньшего количества букв, например, Тортик, то в сервере уже напечатается Тортикдабра. 2) Между сообщениями которые печатаются в консоли сервера большие пропуски, хотя никаких /n вроде нету. Пробовал проверять в консоли клиента отсылаемую инфу, так там все норм, а в консоли сервера уже с пропусками.
Код клиента
using System;       ///////////////////////////////////////////////////
using System.Collections.Generic;/////// Консольный стандарт //////////
using System.Text;  ///////////////////////////////////////////////////
using System.Net.Sockets; ///// Вот он, родимый коллекшн классов //////


namespace tcpclient
{
    class Program
    {
        static void Main(string[] args)
        {
            string data; // Юзерская дата
            byte[] remdata ={ }; // Дата с сервака
            TcpClient Client = new TcpClient(); // создаем экземпляр
            Console.Write("IP to connect to: "); // всякая фигня типа UI
            string ip = Console.ReadLine();
            Console.Write("\r\nPort: ");
            int port = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("\r\nConnecting to server...");
            try
            {
                Client.Connect(ip, port); // попробуем подконнектиться.
            } // если не получится - эксепшн
            catch
            {
                Console.WriteLine("Cannot connect to remote host!");
                return;
            }
            Console.Write("done\r\nTo end, type 'END'");
            Socket Sock = Client.Client; // нах всякие NetStream'ы
            while (true) // базарим с сервером… если достало – пишем END
            {
                Console.Write("\r\n>");
                data = Console.ReadLine();
                if (data == "END")
                    break;
                Sock.Send(Encoding.ASCII.GetBytes(data)); // преобразование
                                                          // типов
                Sock.Receive(remdata);
                Console.Write("\r\n<" + Encoding.ASCII.GetString(remdata));
            }
            Sock.Close();
            Client.Close();
        }
    }
}
Код сервера
using System; /////////////////////////////////////////////////
using System.Collections.Generic;///// Консольный стандарт ////
using System.Text;/////////////////////////////////////////////
using System.Net.Sockets; // Вот он, родимый коллекшн классов /
using System.Threading; // Коллекшн для работы с потоками /////

namespace tcpserver
{
    class Program
    {
        static void Main(string[] args)
        {
            string cmd;
            Console.Write("Port to listen: ");
            int port = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Creating server...");
            Server Serv = new Server(); // Создаем новый экземпляр класса
                                        // сервера
            Serv.Create(port);
           
            while (true)
            {
                cmd = Console.ReadLine(); // Ждем фразы EXIT когда
                                          // понадобится выйти из приложения.
                                          // типа интерактивность.
                if (cmd == "EXIT")
                {
                    Serv.Close(); // раз выход – значит выход. Серв-нах.
                    return;
                }
            }
        }
        public class Server // класс сервера.
        {
            private int LocalPort;
            private Thread ServThread; // экземпляр потока
            TcpListener Listener; // листенер))))
           
            public void Create(int port)
            {
                LocalPort = port;
                ServThread = new Thread(new ThreadStart(ServStart));
                ServThread.Start(); // запустили поток. Стартовая функция –
                                    // ServStart, как видно выше
            }
           
            public void Close() // Закрыть серв?
            {
                Listener.Stop();
                ServThread.Abort();
                return;
            }
       
            private void ServStart()
            {
                Socket ClientSock; // сокет для обмена данными.
                string data;
                byte[] cldata = new byte[1024]; // буфер данных
                Listener = new TcpListener(LocalPort);
                Listener.Start(); // начали слушать
                Console.WriteLine("Waiting connections [" + Convert.ToString(LocalPort) + "]...");
                try
                {
                    ClientSock = Listener.AcceptSocket(); // пробуем принять
                                                          // клиента
                }
                catch
                {
                    ServThread.Abort(); // нет – жаль(
                    return;
                }
                int i=0;
       
                if (ClientSock.Connected)
                {
                    while (true)
                    {
                        try
                        {
                            i = ClientSock.Receive(cldata); // попытка чтения
                                                            // данных
                        }
                        catch
                        {
                        }

                        try
                        {
                            if (i > 0)
                            {
                           
                                data = Encoding.ASCII.GetString(cldata).Trim();
                                Console.WriteLine("<" + data);
                                if (data == "CLOSE") // если CLOSE –
                                                     // вырубимся
                                {
                                    ClientSock.Send(Encoding.ASCII.GetBytes("Closing the server..."));
                                    ClientSock.Close();
                                    Listener.Stop();
                                    Console.WriteLine("Server closed. Reason: client wish! Type EXIT to quit the application.");
                                    ServThread.Abort();
                                    return;
                                }
                                else
                                { // нет – шлем данные взад.
                                    ClientSock.Send(Encoding.ASCII.GetBytes("Your data: " + data));
                                }
                            }
                        }
                        catch
                        {
                            ClientSock.Close(); // ну эт если какая хрень..
                            Listener.Stop();
                            Console.WriteLine("Server closing. Reason: client offline. Type EXIT to quit the application.");
                            ServThread.Abort();
                        }
                    }
                }
            }
        }
    }
}

Ноябрь 04, 2012, 01:58:56 am
Ответ #1

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2453
  • Репутация:
    153
    • Просмотр профиля
Не возился ещё с серверами-клиентами в юнити...
Но помоему, тебе  надо перевод строки и каретки, надо делать, при каждом выводе в консоль:

Console.WriteLine("текст сообщения\r\n");

А вот это точно незнаю что даст, не пробовал, но возможно наоборот, убивает лишний перевод строки:
Console.WriteLine("текст сообщения\r\n{0}");

поскольку используется так:
Console.WriteLine("текст сообщения\r\n{0}", text);


Кстати глянь как тут с консолью в C# работают:
http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx
« Последнее редактирование: Ноябрь 04, 2012, 02:06:44 am от NewBee »

Ноябрь 04, 2012, 17:05:59 pm
Ответ #2

lawliet93

  • Частный гость

  • Оффлайн
  • ***

  • 113
  • Репутация:
    -2
    • Просмотр профиля
Не возился ещё с серверами-клиентами в юнити...
Но помоему, тебе  надо перевод строки и каретки, надо делать, при каждом выводе в консоль:

Console.WriteLine("текст сообщения\r\n");

А вот это точно незнаю что даст, не пробовал, но возможно наоборот, убивает лишний перевод строки:
Console.WriteLine("текст сообщения\r\n{0}");

поскольку используется так:
Console.WriteLine("текст сообщения\r\n{0}", text);


Кстати глянь как тут с консолью в C# работают:
http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx
да я знаю как работать. просто моя проблема и правда не понятна. думал мож кто-то другой знает в чем дело. Console.WriteLine печатает строку и  в конце ставит перенос строки. а ConsoleWriteLine("что-то {0} , {1}", var_a,var_b) это типа форматированный вывод {0} означает номер переменной которая записывается после закрытия " и запятой. тут {0} = var_a, {1}=var_b.