Клиент-серверная связь. Сокеты. Помогите пожалуйста
| |
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 |
Сэнсэй
Сейчас нет на сайте
| Да, копипаст - это сила!
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 |
|
| |
|