Отправка строки на сервер с клиента в C # - PullRequest
5 голосов
/ 11 февраля 2011

Я пишу простую тестовую программу для отправки строки с клиента на сервер и последующего отображения текста в программе сервера. Как бы я поступил так.

Вот мой код клиента.

using System;
using System.Net;
using System.Net.Sockets;


    class client
    {

        static String hostName = Dns.GetHostName();

        public static void Main(String[] args)
        {
            String test = Console.ReadLine();

            IPHostEntry ipEntry = Dns.GetHostByName(hostName);
            IPAddress[] addr = ipEntry.AddressList;

            //The first one in the array is the ip address of the hostname
           IPAddress ipAddress = addr[0];


            TcpClient client = new TcpClient();

            //First parameter is Hostname or IP, second parameter is port on which server is listening
            client.Connect(ipAddress, 8);


            client.Close();
        }
    }

Вот мой код сервера

using System;
using System.Net;
using System.Net.Sockets;

class server
{
    static int port = 8;
    static String hostName = Dns.GetHostName();
    static IPAddress ipAddress;

    public static void Main(String[] args)
    {
        IPHostEntry ipEntry = Dns.GetHostByName(hostName);

        //Get a list of possible ip addresses
        IPAddress[] addr = ipEntry.AddressList;

        //The first one in the array is the ip address of the hostname
        ipAddress = addr[0];

        TcpListener server = new TcpListener(ipAddress,port);

        Console.Write("Listening for Connections on " + hostName + "...\n");

        //start listening for connections
        server.Start();

        //Accept the connection from the client, you are now connected
        Socket connection = server.AcceptSocket();

        Console.Write("You are now connected to the server\n\n");


        int pauseTime = 10000;
        System.Threading.Thread.Sleep(pauseTime);

        connection.Close();


    }


}

1 Ответ

8 голосов
/ 11 февраля 2011

Вы можете использовать перегрузки Send и Receive при Socket.Также существует асинхронная версия с помощью методов BeginSomething & EndSomething.

Вы отправляете необработанные байты, поэтому вам нужно будет выбрать протокол, каким бы простым он ни был.Чтобы отправить текст, выберите кодировку (я бы использовал UTF-8) и получите необработанные байты с Encoding.GetBytes.

Пример:

Byte[] bytes = Encoding.UTF8.GetBytes("Royale With Cheese");

UTF8это статическое свойство класса Encoding, оно для вашего удобства.

Затем вы можете отправить данные на сервер / клиент с помощью:

int sent = connection.Send(bytes);

Receive:

Byte[] bytes = new Bytes[100]; 
int received = connection.Receive(bytes);

Это выглядит легко, но есть предостережения.Соединение может быть разорвано в любое время, поэтому вы должны быть готовы к исключениям, особенно SocketException.Также, если вы посмотрите на примеры, вы увидите, что у меня есть две переменные sent и received.Они содержат сколько байтов Send и Receive фактически отправлено.Вы не можете полагаться на то, что сокет отправляет или получает все данные (особенно не при получении, что, если другая сторона отправила меньше, чем вы ожидали?)

Один из способов сделать это - зациклить и отправить, пока все данные не будут отправлены.отображается как отправленный:

var bytes = Encoding.UTF8.GetBytes("Royale With Cheese");
int count = 0;
while (count < bytes.Length) // if you are brave you can do it all in the condition.
{
    count += connection.Send(
        bytes, 
        count, 
        bytes.Length - count, // This can be anything as long as it doesn't overflow the buffer, bytes.
        SocketFlags.None)
}

Send и Receive синхронны, они блокируются, пока не отправят что-либо.Вам, вероятно, следует установить какое-либо значение времени ожидания для сокета ( Socket.SendTimeout & Socket.ReceiveTimeout .) По умолчанию 0, что означает, что они могут блокироваться навсегда.

Теперь как насчет получения?Попробуем сделать аналогичный цикл.

int count = 0;
var bytes = new Byte[100];
do
{
    count += connection.Receive(
        bytes,
        count,
        bytes.Length - count,
        SocketFlags.None);
} while (count < bytes.Length);

Хмм.Ну ... что будет, если клиент отправит меньше 100?Мы блокируем, пока не истечет время ожидания, если оно есть, или если клиент отправит достаточно данных.Что произойдет, если клиент отправит более 100?Вы получите только 100 первых байтов.

В вашем случае мы можем попробовать прочитать очень маленькие суммы и распечатать.Чтение, печать, зацикливание:

var sunIsBurning = true;
while (sunIsBurning) {
    var bytes = new Byte[16];
    int received = socket.Receive(bytes);
    if (received > 0)
        Console.Out.WriteLine("Got {0} bytes. START:{1}END;", received, Encoding.UTF8.GetString(bytes));
}

Здесь мы говорим: «получать данные в 16-байтовых блоках, пока sunIsBurning, декодировать как UTF-8».Это означает, что данные, отправленные другой стороной, должны быть в формате UTF-8, иначе вы получите исключение (вероятно, оно должно быть перехвачено вами). Это также означает, что сервер прекратит прием только при сбое соединения.

Если вы получили 15 байтов, и клиент разорвал соединение, эти 15 байтов никогда не будут напечатаны.Для этого вам потребуется лучшая обработка ошибок:)

В большинстве случаев неперехваченное исключение убьет ваше приложение;нежелательно для сервера.

«сбой соединения» может означать много вещей , возможно, соединение было сброшено узлом или ваша сетевая карта загорелась.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...