Понедельник, 06 Мая 2024, 06:41

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Форум игроделов » Программирование » Общие обсуждения программистов » Клиент-серверная связь. Сокеты. Помогите пожалуйста
Клиент-серверная связь. Сокеты. Помогите пожалуйста
SaiteiДата: Суббота, 18 Августа 2012, 18:12 | Сообщение # 21
старожил
Сейчас нет на сайте
karuy, я попробовал запихнуть все три исключения через "||". Компилятор люто ругается
karuyДата: Суббота, 18 Августа 2012, 18:21 | Сообщение # 22
заслуженный участник
Сейчас нет на сайте
Code
try  
     {  
        s.Listen(30);  
     }  
     catch ( ObjectDisposedException e )   
     {  
        Console.WriteLine(e->Message );  
     }
     catch ( SocketException e )   
     {  
        Console.WriteLine(e->Message );  
     }

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

Добавлено (18.08.2012, 18:21)
---------------------------------------------

Quote (Saitei)
karuy, я попробовал запихнуть все три исключения через "||". Компилятор люто ругается

Грубая лажа =) Почему? - На домашнее задание))
SaiteiДата: Суббота, 18 Августа 2012, 19:52 | Сообщение # 23
старожил
Сейчас нет на сайте
karuy, да мне просто лень было много раз писать catch. Вот и написал компьютеру "либо то, либо это, либо сё" xD
Роюсь в справке

Добавлено (18.08.2012, 19:11)
---------------------------------------------
Плачу горькими слезами

Code
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;

namespace server
{
     class mainStart
     {
         static void Main(string[] args)
         {
             IPEndPoint Addr = null; //IP и порт
             int portInUse = 8563;
             System.Console.Title="Сервер"; /*Название окна*/
             System.Console.ForegroundColor = ConsoleColor.Green; /*Весь текст в консоли теперь зелёный! ^^*/
             Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); /*Создание основного сокета. AddressFamily - указание на тип семейства адресов (InterNetwork = IPv4),  
                    * SocketType - указание на тип сокетного подключения,  ProtocolType - используемый протокол для передачи данных */
             Console.WriteLine("Запуск сервера...");
             Addr = new IPEndPoint(IPAddress.Any, portInUse);
             s.Bind(Addr);
             try
             {
                 Console.WriteLine("Прослушиваемый порт: " + portInUse);
                 Console.WriteLine("Адрес: " + Addr);
                 s.Listen(30); /*Порт ставим в режим прослушивания. Поддерживаем 30 подключений*/
             }
             catch (ObjectDisposedException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.WriteLine(e.Message);
             }
             catch (SocketException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.WriteLine(e.Message);
             }
             catch (InvalidOperationException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.WriteLine(e.Message);
             }
             Console.WriteLine("Waiting...");
             Socket sAccept = s.Accept(); /*Ожидаем подключения*/
             Console.WriteLine("Есть соединение!");
             while (true)
             {
                 byte[] msg = new byte[sAccept.Available];
                 sAccept.Receive(msg); /*Принимаем сообщение*/
                 Console.WriteLine(Encoding.UTF8.GetString(msg)); /*Конвертируем и выводим на экран*/
             }
         }
     }
}


Это сервер. А вот в клиенте вечно ругается на connect по addr. Пишет что адрес несовместим с IPv4 и бла-бла-бла. У меня печаль, ребят...

Добавлено (18.08.2012, 19:52)
---------------------------------------------
Кто-нибудь может на короткое время взять меня под своё крыло? Просто часто я нуждаюсь в наставлениях... Справку читаю, сам экспериментирую. Просто помощь нужна

karuyДата: Суббота, 18 Августа 2012, 20:20 | Сообщение # 24
заслуженный участник
Сейчас нет на сайте
Код покажы клиента, я ж не телепат.
SaiteiДата: Суббота, 18 Августа 2012, 20:31 | Сообщение # 25
старожил
Сейчас нет на сайте
karuy, код клиента слизан с примера:
Code

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;

namespace client
{
     class classClient
     {
         static void Main()
         {
             IPEndPoint Addr = null; //конечная точка(IP и порт)
         Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Создаем основной сокет
         IPAddress ipAddress = null; //IP-адрес
         Console.Title = "Клиент";
         ipAddress = Dns.GetHostEntry("127.0.0.1").AddressList[0];
         Addr = new IPEndPoint(ipAddress, 8563); //"localhost" = 127.0.0.1
         s.Connect(Addr); //Коннектимся к срверу
         while (true) //Вечная истина <img src="http://s12.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
         {
             byte[] msg = Encoding.UTF8.GetBytes(Console.ReadLine()); //Конвертируем
             s.Send(msg); //Отправляем
         }
         }
     }
}
karuyДата: Суббота, 18 Августа 2012, 20:35 | Сообщение # 26
заслуженный участник
Сейчас нет на сайте
Попробуй все-таки отсюда клиент скопипастить.
http://forum.vingrad.ru/index.php?showtopic=35842&
SaiteiДата: Суббота, 18 Августа 2012, 20:43 | Сообщение # 27
старожил
Сейчас нет на сайте
*начал танцевать на столе и безумно орать* ПАШЕТ
ArchidoДата: Суббота, 18 Августа 2012, 20:53 | Сообщение # 28
Сэнсэй
Сейчас нет на сайте
Да, копипаст - это сила! biggrin

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


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SaiteiДата: Суббота, 18 Августа 2012, 21:01 | Сообщение # 29
старожил
Сейчас нет на сайте
Archido, книжки листаю, есть) В справке из майкрасофта роюсь

Ну да)) Теперь придется каждую строчку копать, мастырить... Эээх... Я радовался от надписи "Есть соединение!". Теперь надо будет меседж передать и вывести на экран))
karuyДата: Суббота, 18 Августа 2012, 21:30 | Сообщение # 30
заслуженный участник
Сейчас нет на сайте
Saitei, По руках тебя нужно бить за то, что ты узнаешь о операторах из разбираемых примеров. Не поленись - почитай книжку.
SaiteiДата: Суббота, 18 Августа 2012, 23:57 | Сообщение # 31
старожил
Сейчас нет на сайте
karuy, операторы многие знал. Честно-честно) Все кроме try + catch. Да и после того, как всё запахало, я врубился в вопрос и не поленился прочесть про них)

Добавлено (18.08.2012, 23:57)
---------------------------------------------
Объясните пожалуйста разницу между синхронными и асинхронными серверами

ArchidoДата: Воскресенье, 19 Августа 2012, 00:10 | Сообщение # 32
Сэнсэй
Сейчас нет на сайте
Quote (Saitei)
Объясните пожалуйста разницу между синхронными и асинхронными серверами

Синхронный сервер приостанавливает свою "работу", пока идет обмен данными со своими клиентами. Асинхронный же умеет делать и то и другое одновременно (делать свою "работу" и обрабатывать / получать данные из сети). Думаю, стоит почитать на тему блокирующих и неблокирующих сокетов.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SaiteiДата: Воскресенье, 19 Августа 2012, 00:22 | Сообщение # 33
старожил
Сейчас нет на сайте
Как-то можно вывести на консоль от кого приходят пакеты?) ip-адрес?
ArchidoДата: Воскресенье, 19 Августа 2012, 00:31 | Сообщение # 34
Сэнсэй
Сейчас нет на сайте
Quote (Saitei)
Как-то можно вывести на консоль от кого приходят пакеты?) ip-адрес?

Можно или звать для приема Socket.ReceiveFrom


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Воскресенье, 19 Августа 2012, 00:42
SaiteiДата: Воскресенье, 19 Августа 2012, 01:11 | Сообщение # 35
старожил
Сейчас нет на сайте
Quote (Archido)
на тему блокирующих и неблокирующих сокетов.

зачем?
ArchidoДата: Воскресенье, 19 Августа 2012, 08:42 | Сообщение # 36
Сэнсэй
Сейчас нет на сайте
Saitei
Т.к. это имеет отношение к теме синхронности и асинхронности сетевых приложений.
И наверное вчера ночью чутка не так понял вопрос - конкретно синхронный сервер выполняет обработку сетевых данных / запросов из вне - последовательно (очередь и один единственный поток), а асинхронный соответственно - параллельно (например, каждому клиенту - свой поток (thread)). Наверное речь об этом была.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SaiteiДата: Воскресенье, 19 Августа 2012, 16:07 | Сообщение # 37
старожил
Сейчас нет на сайте
Archido,
http://msdn.microsoft.com/en-us/library/fx6588te
http://msdn.microsoft.com/en-us/library/6y0e13d3
ещё не ковырялся... Вот и спрашиваю

Добавлено (19.08.2012, 16:07)
---------------------------------------------

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

// State object for reading client data asynchronously
public class StateObject {
     // Client  socket.
     public Socket workSocket = null;
     // Size of receive buffer.
     public const int BufferSize = 1024;
     // Receive buffer.
     public byte[] buffer = new byte[BufferSize];
// Received data string.
     public StringBuilder sb = new StringBuilder();   
}

public class AsynchronousSocketListener {
     // Thread signal.
     public static ManualResetEvent allDone = new ManualResetEvent(false);

     public AsynchronousSocketListener() {
     }

     public static void StartListening() {
         // Data buffer for incoming data.
         byte[] bytes = new Byte[1024];

         // Establish the local endpoint for the socket.
         // The DNS name of the computer
         // running the listener is "host.contoso.com".
         IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
         IPAddress ipAddress = ipHostInfo.AddressList[0];
         IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

         // Create a TCP/IP socket.
         Socket listener = new Socket(AddressFamily.InterNetwork,
             SocketType.Stream, ProtocolType.Tcp );

         // Bind the socket to the local endpoint and listen for incoming connections.
         try {
             listener.Bind(localEndPoint);
             listener.Listen(100);

             while (true) {
                 // Set the event to nonsignaled state.
                 allDone.Reset();

                 // Start an asynchronous socket to listen for connections.
                 Console.WriteLine("Waiting for a connection...");
                 listener.BeginAccept(  
                     new AsyncCallback(AcceptCallback),
                     listener );

                 // Wait until a connection is made before continuing.
                 allDone.WaitOne();
             }

         } catch (Exception e) {
             Console.WriteLine(e.ToString());
         }

         Console.WriteLine("\nPress ENTER to continue...");
         Console.Read();
          
     }

     public static void AcceptCallback(IAsyncResult ar) {
         // Signal the main thread to continue.
         allDone.Set();

         // Get the socket that handles the client request.
         Socket listener = (Socket) ar.AsyncState;
         Socket handler = listener.EndAccept(ar);

         // Create the state object.
         StateObject state = new StateObject();
         state.workSocket = handler;
         handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
             new AsyncCallback(ReadCallback), state);
     }

     public static void ReadCallback(IAsyncResult ar) {
         String content = String.Empty;
          
         // Retrieve the state object and the handler socket
         // from the asynchronous state object.
         StateObject state = (StateObject) ar.AsyncState;
         Socket handler = state.workSocket;

         // Read data from the client socket.  
         int bytesRead = handler.EndReceive(ar);

         if (bytesRead > 0) {
             // There  might be more data, so store the data received so far.
             state.sb.Append(Encoding.ASCII.GetString(
                 state.buffer,0,bytesRead));

             // Check for end-of-file tag. If it is not there, read  
             // more data.
             content = state.sb.ToString();
             if (content.IndexOf("<EOF>") > -1) {
                 // All the data has been read from the  
                 // client. Display it on the console.
                 Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                     content.Length, content );
                 // Echo the data back to the client.
                 Send(handler, content);
             } else {
                 // Not all data received. Get more.
                 handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                 new AsyncCallback(ReadCallback), state);
             }
         }
     }
      
     private static void Send(Socket handler, String data) {
         // Convert the string data to byte data using ASCII encoding.
         byte[] byteData = Encoding.ASCII.GetBytes(data);

         // Begin sending the data to the remote device.
         handler.BeginSend(byteData, 0, byteData.Length, 0,
             new AsyncCallback(SendCallback), handler);
     }

     private static void SendCallback(IAsyncResult ar) {
         try {
             // Retrieve the socket from the state object.
             Socket handler = (Socket) ar.AsyncState;

             // Complete sending the data to the remote device.
             int bytesSent = handler.EndSend(ar);
             Console.WriteLine("Sent {0} bytes to client.", bytesSent);

             handler.Shutdown(SocketShutdown.Both);
             handler.Close();

         } catch (Exception e) {
             Console.WriteLine(e.ToString());
         }
     }

     public static int Main(String[] args) {
         StartListening();
         return 0;
     }
}


Вот строка:
Code
// Received data string.
     public StringBuilder sb = new StringBuilder();  

что она делает конкретно в этом коде?
ArchidoДата: Воскресенье, 19 Августа 2012, 16:21 | Сообщение # 38
Сэнсэй
Сейчас нет на сайте
Quote (Saitei)
что она делает конкретно в этом коде?

Создается объект класса StringBuilder? А потом созданный объект sb юзается для приема данных, далее по коду. Сам StringBuilder - строковый Pool, в MSDN по сылке о нем более подробно говорится.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Воскресенье, 19 Августа 2012, 16:28
SaiteiДата: Воскресенье, 19 Августа 2012, 18:27 | Сообщение # 39
старожил
Сейчас нет на сайте
Сервер переписываю. Пока что всё ок вроде?

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace asServer
{
     class server
     {
         public static void serverStart()  
         {
             System.Console.Title = "Server";
             System.Console.ForegroundColor = ConsoleColor.Green;
             IPEndPoint fullAddress = null; /* x.x.x.x:xxxx; (IP:port)*/
             System.Console.WriteLine("Какой порт поставить в режим прослушивания?");
             System.Console.Write(">>");
             int portInUse, online;
             string pPort = System.Console.ReadLine();
             int.TryParse(pPort, out portInUse);
             System.Console.WriteLine("Сколько допускать подключений к порту " + portInUse + "?");
             System.Console.Write(">>");
             string tOnline = System.Console.ReadLine();
             int.TryParse(tOnline, out online);
             System.Console.WriteLine("Запускаем сервер...");
             Socket mySock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             System.Console.WriteLine("port: " + portInUse);
             System.Console.WriteLine("Количество возможных подключений: " + online);
             try
             {
                 fullAddress = new IPEndPoint(IPAddress.Any, portInUse);
                 System.Console.WriteLine("Ставим порт " + portInUse + " в режим прослушивания...");
                 mySock.Bind(fullAddress);
                 mySock.Listen(online);
             }
             catch (ObjectDisposedException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.Write("Тект ошибки: ");
                 Console.WriteLine(e.Message);
             }
             catch (SocketException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.Write("Тект ошибки: ");
                 Console.WriteLine(e.Message);
             }
             catch (InvalidOperationException e)
             {
                 Console.WriteLine("We have some problems :(");
                 Console.Write("Тект ошибки: ");
                 Console.WriteLine(e.Message);
             }

         }
         public static void Main(string[] args)
         {
             serverStart();
             System.Console.ReadKey();
         }
     }
}

Добавлено (19.08.2012, 18:27)
---------------------------------------------
переписал клиент и сервер. Кто-то напишите мне в ЛС свои контактные данные... Я всё это дело связал (Listen\Agree), но теперь нужно окончательно понять как переменные передавать

ArchidoДата: Воскресенье, 19 Августа 2012, 19:03 | Сообщение # 40
Сэнсэй
Сейчас нет на сайте
Quote (Saitei)
Я всё это дело связал (Listen\Agree), но теперь нужно окончательно понять как переменные передавать

Ну, а чего там понимать? Самый простой, в данном случае (на базе вышеописанного кода), способ - передавать все через строки.
У тебя есть некоторая переменная, ты делаешь MyVar.ToString() - получаешь ее в виде строки, ну и формируешь для отправки общую строку типа: "MyVar:" + MyVar.ToString() + '#'. Тут "MyVar:" - идентификатор, он нужен для того, чтобы определить к какой переменной относится этот мини "пакет", '#' - символ разделитель, с помощью него можно отличить один "пакет" от другого. Передавать можно сколько угодно переменных.
При приеме получаешь пачку этих строк, разбираешь их, основываясь на '#", и каждый получившийся "пакет" парсишь, узнаешь идентификатор и данные -> заносишь в переменную.


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Воскресенье, 19 Августа 2012, 19:03
Форум игроделов » Программирование » Общие обсуждения программистов » Клиент-серверная связь. Сокеты. Помогите пожалуйста
  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг