Сетевое программирование в .NET. Расшифровка IP-адреса (IP address specification). Обеспечение надежности доставки пакетов, страница 26

class SocketClient

{

public static void Main()

{

int port = 27015;

string

host = "localhost",     // Имя сервера (Вы можете использовать другое, реальное имя)

header = "Trying to connect to: " + host + " on port: " + port.ToString(),

line = "\n" + new string('\u2500', header.Length) + "\n";

Console.WriteLine (header + line);

TcpClient client = null;

try

{

client = new TcpClient();

client.Connect (host, port);

byte[] buffer = new byte[512];

int bytes = client.GetStream().Read(buffer, 0, buffer.Length);

string tip = Encoding.ASCII.GetString(buffer).Substring(0, bytes);

Console.WriteLine("Received {0} bytes:\n-->{1}", bytes, tip);

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

return;

}

finally

{

if (client != null)

client.Close();

}

Console.ReadLine();

}

}

Однопроходовый алгоритм клиентского приложения настолько прост, что не нуждается в комментарии. Отметим лишь, что класс TcpClient реализует лишь самые простые функции сетевого разъема (Socket). Если вам нужно реализовать более сложное поведение, то его следует заменить на класс Socket.

¨  Постройте оба проекта и запустите сервер из окна файлового менеджера (вне студии),

¨  Запустите клиента таким же образом (из окна файлового менеджера) и убедитесь, что он получил совет дня от сервера, а сервер сообщил, что он обработал клиента,

¨  Не закрывая окно первого клиента, повторите запуск еще одного клиента и наблюдайте за сообщениями как клиента, так и сервера.

¨  Замените имя сервера на реальное (если вы его знаете), не "localhost", перекомпилируйте клиентское приложение и вновь проверьте его работу. Сервер при этом можно не останавливать.

¨  Проверьте возможность использовать другой номер порта.

Создаем приложение типа Chat

Удалите из существующего решения два последних проекта (файлы останутся невредимыми) и добавьте два новых проекта типа Visual C# Console Application. Один (с именем ChatServer) будет выполнять роль сервера, а второй (с именем ChatClient)—клиента. В сценарии типа Chat оба приложения выполняют роль как клиента, так и сервера, и тем не менее одно из них должно быть модератором сессии (это калька с английского: председатель заседания). Именно его надо запустить в первую очередь, в нем надо создать сетевой разъем и начать прослушивание сети. При появлении клиента модератор создает новый, второй разъем (при этом можно просто заменить ссылку), по которому и будет происходить обмен. Следующие рисунки иллюстрируют сказанное.

 

Левое окно принадлежит серверному проекту, в нем вы видите, что прослушивание сети происходит с помощью разъема, начальный конец которого LocalEndPoint = 169.254.13.32:27015 (удаленный конец соединения отсутствует). После подключения клиента с именем Red разъем меняется, его концевым узлом соединения становится RemoteEndPoint=169.254.13.32:1068, а начальный конец не изменяется. Номер порта (1068) для клиентского приложения выбран системой автоматически. В следующий раз он может быть другим. Рассмотрим код серверного приложения. Некоторые его фрагменты вы должны написать самостоятельно.

class ChatServer

{

static string nick; // Nickname пользователя

static int port;     // Номер порта локальной машины

public static void GetNick()

{

// Запросите строку текста (nickname) и обрежте ее, если она длиннее 15 символов

nick = hostName + "." + nick + ": ";  // Образуем сложный nick

}

static void Main()

{

port = 27015;

hostName = Dns.GetHostName();

GetNick();

Chat();

}

static void Chat()

{

try

{

Socket socket = // Создайте Socket

IPHostEntry host = Dns.GetHostEntry (hostName);

IPEndPoint point = new IPEndPoint (// Задайте параметры);

// Привяжите разъем socket к начальному концу point и заставьте его слушать сеть

Console.WriteLine("\nMy address: {0}\nWaiting for a client to connect...", point);

socket = // Ждите, когда клиент подключится

string client = ((IPEndPoint) socket.RemoteEndPoint).ToString();

Console.WriteLine("I am connected to {0}\n", client);